内部Java同步静态方法:在静态变量的关系之前发生

时间:2015-07-01 07:13:03

标签: java multithreading synchronized volatile java-memory-model

同步类方法中的静态变量更新是否保证以前发生过?以此为例:

public class MyClass {
    private static boolean isDone = false;

    public static synchronized doSomething() {
        if (!isDone) {
            // ...
        }

        isDone = true;
    } 
}

在此同步类方法中更新后,变量isDone(不是volatile)是否对所有线程可见?根据我的理解,MyClass.class本身的同步不能保证其静态变量的所有更新都对其他线程可见,因为其他线程可能有一个本地缓存。

3 个答案:

答案 0 :(得分:2)

发生 - 之前是两个事件之间的关系。您指出的事件之一:“更新到同步类方法中的静态变量”。你有什么其他事件?普通读取另一个线程中的变量?不,在另一个线程中的普通阅读不参与发生在之前的关系。

也就是说,你是正确的建议同步不能保证变量的所有更新都对其他线程可见。

UPDT为了保证变量的所有更新对其他线程可见,该线程还必须同步它们的读取,即在同步类方法中进行读取。

答案 1 :(得分:0)

我在这里找到答案:https://www.cs.umd.edu/users/pugh/java/memoryModel/jsr-133-faq.html#synchronization

  

在我们退出synchronized块之后,我们释放了监视器,它具有将缓存刷新到主内存的效果,因此该线程所做的写操作对其他线程是可见的。在我们进入同步块之前,我们获取监视器,它具有使本地处理器高速缓存无效的效果,以便从主存储器重新加载变量。然后,我们将能够看到前一版本中显示的所有写入。

答案 2 :(得分:0)

以下是一种更简单的思考方式如果你遵循良好的编码习惯:

如果它synchronized你不必担心它。

那是因为,如果线程A更新了任何变量然后释放了一个锁,那么在线程B锁定相同的锁之后线程B可以看到更新,而如果你跟随好了编码练习,那么您的synchronized块将尽可能小:您不会触及同步块内不需要同步的任何共享变量。而且,如果你遵循良好的编码习惯,那么每次访问变量(写或读)都将被同步。