Java中的守卫块。我应该在哪里更新条件变量?

时间:2015-04-27 17:14:44

标签: java multithreading

我使用volatile条件变量,但我认为volatile是多余的。此外,我不太确定我是否正确地理解了https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/package-summary.html#MemoryVisibility这一点:

  

监视器的解锁(同步块或方法退出)   发生在每个后续锁定之前(同步块或方法)   那个监视器的入口)。而且因为发生在之前的关系   是传递的,解锁之前线程的所有动作   发生 - 在任何线程锁定之后的所有操作之前发生   监视。

随后调用synchronized块。但是synchronized块中执行的分配结果是否对所有后续synchronized块可见?

以下是一个示例应用。

package sample;

public class Foo {

    private boolean shouldWait;
    private final Object lock = new Object();

    void blockThread() {
        synchronized (lock) {
            shouldWait = true;
            while (shouldWait) {
                try {
                    lock.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    void notifyThread() {
        synchronized (lock) {
            shouldWait = false;
            lock.notify();
        }
    }
}

测试。

package sample;

public class Main {

    private static Foo foo = new Foo();

    public static void main(String[] args) {
        new Thread(new Runnable() {

            @Override
            public void run() {
                foo.blockThread();
            }
        }).start();
        try {
            Thread.sleep(200);
        } catch (InterruptedException e) {
        }
        new Thread(new Runnable() {

            @Override
            public void run() {
                foo.notifyThread();
            }
        }).start();
    }

}

1 个答案:

答案 0 :(得分:1)

  

随后调用同步块。但是,在同步块中执行的赋值结果是否对所有后续同步块可见?

是。 volatile写道具有相同的关系。 volatile写入之前的所有操作都会在所有后续读取之前发生。