繁体   English   中英

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

[英]Inside Java synchronized static method: happens before relationship for static variable

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

public class MyClass {
    private static boolean isDone = false;

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

        isDone = true;
    } 
}

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

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

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

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

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

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

如果您遵循良好的编码实践,这是一种更简单的思考方式:

如果它是synchronized你不必担心它。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM