这里是代码
class Aux implements Runnable {
private Boolean isOn = false;
private String statusMessage;
private final Object lock;
public Aux(String message, Object lock) {
this.lock = lock;
this.statusMessage = message;
}
@Override
public void run() {
for (;;) {
synchronized (lock) {
if (isOn && "left".equals(this.statusMessage)) {
isOn = false;
System.out.println(statusMessage);
} else if (!isOn && "right".equals(this.statusMessage)) {
isOn = true;
System.out.println(statusMessage);
}
if ("left".equals(this.statusMessage)) {
System.out.println("left " + isOn);
}
}
}
}
}
public class Question {
public static void main(String [] args) {
Object lock = new Object();
new Thread(new Aux("left", lock)).start();
new Thread(new Aux("right", lock)).start();
}
}
我希望在这段代码中看到:
左、右、左、右等
但是当带有“left”消息的线程将 isOn 更改为 false 时,带有“right”消息的线程看不到它并且我得到(“right true”和“left false”控制台消息),左线程没有得到isOn 为真,但正确的线程无法更改它,因为它总是看到旧的 isOn 值(真)。
当我将 volatile 修饰符添加到 isOn 时,没有任何变化,但如果我将 isOn 更改为具有 boolean 字段的某个类并更改此字段,则线程会看到更改并且它工作正常
提前致谢。
最佳答案
isOn
是线程局部变量,因此当一个线程修改它时,另一个线程将看不到更改。当您使用带有 boolean 字段的类时,您可能会为每个线程提供该类的相同实例,这意味着这些线程将看到其他线程所做的更改。但是,您创建了 Aux
的两个实例,而不是只使用一个。
如果您希望它在两个不同的实例上工作,请尝试将 static
修饰符(连同 volatile
修饰符)添加到 Boolean
field ;否则,不要创建第二个 Aux
。
关于Java 线程看不到共享的 boolean 值更改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17385211/