Java线程看不到共享的布尔值更改 [英] java threads don't see shared boolean changes
问题描述
代码在这里
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();
}
}
在这段代码中,我希望看到:
In this code I expect to see:
左,右,左,右等等,
但是当带有"left"消息的线程将isOn更改为false时,带有"right"消息的线程看不到它,并且我得到了消息("right true"和"left false"控制台消息),所以左侧线程没有得到isOn为true,但是正确的Thread不能更改它,因为它总是看到旧的isOn值(true).
but when Thread with "left" message changes isOn to false, Thread with "right" message don't see it and I get ("right true" and "left false" console messages), left thread don't get isOn in true, but right Thread can't change it cause it always see old isOn value (true).
当我向isOn添加volatile修饰符时,什么都没有改变,但是如果我将isOn更改为具有布尔字段的某个类并更改此字段,则线程会发生变化并且可以正常工作
When i add volatile modifier to isOn nothing changes, but if I change isOn to some class with boolean field and change this field then threads are see changes and it works fine
谢谢.
推荐答案
isOn
是线程局部变量,因此当一个线程对其进行修改时,另一个线程将看不到更改.当您使用带有布尔字段的类时,您可能会给每个线程相同的类实例,这意味着这些线程将看到其他线程所做的更改.但是,您将创建两个 Aux
实例,而不是仅使用一个实例.
isOn
is a thread local variable, so when one thread modifies it, the other thread won't see the changes. When you use a class with a boolean field, you're presumably giving each thread the same instance of the class, meaning that the threads will see changes made by the other threads. However, you create two instances of Aux
instead of using just one.
如果您希望它在两个不同的实例上运行,请尝试将 static
修饰符(以及 volatile
修饰符)添加到 Boolean
场地;否则,请勿创建第二个 Aux
.
If you want it to work on two different instances, try adding the static
modifier (along with the volatile
modifier) to the Boolean
field; otherwise, don't create a second Aux
.
这篇关于Java线程看不到共享的布尔值更改的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!