gpt4 book ai didi

java - 这与线程和阻塞队列有关吗?

转载 作者:行者123 更新时间:2023-11-30 08:24:35 25 4
gpt4 key购买 nike

我想知道是否可以让线程访问类的实例因此您可以对该类的某些成员/变量执行操作。

比如我有一个主线程和一个线程。我让第二个线程访问主类的实例所以我可以对 x 执行操作。

但是,如果在未来的某个时候我决定对 x 进行操作怎么办?在主线程中?或者只是简单地从 x 读取。如果另一个线程和主线程都怎么办线程要同时读取x?

按照我在代码中构建它的方式,这完全没问题吗?

package test;

import java.lang.Thread;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

class AThread extends Thread {

Test test;

AThread(Test test) {
this.test = test;
}
BlockingQueue<String> queue = new LinkedBlockingQueue<String>();

public void run() {
String msg;
while ((msg = queue.poll()) != null) {
// Process the message
//System.out.println(msg); //should print "hello"
if (msg.equals("up")) {
test.setX(test.getX()+1);
System.out.println(test.getX());
}
}
}
}

public class Test {
AThread aThread;
private int x = 5;

void setX(int x){
this.x = x;
}

int getX(){
return x;
}

Test() throws InterruptedException{
System.out.println("MainThread");
aThread = new AThread(this);
aThread.start();
while (true) {
aThread.queue.put("up");

}
}

public static void main(String[] args) throws InterruptedException {
new Test();
}
}

不仅是成员“x”,而且“Test”类中​​可能还有更多我希望能够对其执行操作(例如读/写)的成员。

这样的结构可行吗?如果不是,应该修复什么?

最佳答案

您的代码有几个问题。

考虑这一行:

    aThread = new AThread(this);

在构造函数的某处传递 this 总是一个坏主意。这与线程无关……但是。原因是“某处”可能会调用 this 上的方法,并且该方法可能会在尚未调用其构造函数的子类中被覆盖,并且它可能会以灾难告终,因为该覆盖可能使用一些尚未初始化的子类字段。

现在,当线程出现时,事情变得更糟。保证线程可以正确访问在线程启动之前创建的类实例。但在你的情况下,它还没有创建,因为构造函数还没有完成!由于下面的无限循环,它不会很快结束:

    while (true) {
aThread.queue.put("up");

}

因此,您有一个与线程启动并行运行的对象创建。 Java 不保证在这种情况下线程会看到初始化的类(即使没有循环)。

这也是为什么在构造函数中启动线程被认为是一个坏主意的原因之一。在这种情况下,某些 IDE 甚至会发出警告。请注意,在构造函数中运行无限循环也可能不是一个好主意。

如果您将代码移动到 run() 类方法中并在 main() 中执行 new Test().run() >,那么你的代码看起来会很好,但你担心是对的

However, what if at some point in the future I decide to do operations on x in the main thread?

最好的办法是让主线程在对象传递给线程后立即忘记它:

public static void main(String[] args) throws InterruptedException {
AThread aThread = new AThread(new Test());
aThread.start();
while (true) {
aThread.queue.put("up");
}
}

关于java - 这与线程和阻塞队列有关吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22868197/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com