Java线程看不到共享的布尔值更改 [英] java threads don't see shared boolean changes

查看:61
本文介绍了Java线程看不到共享的布尔值更改的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

代码在这里

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆