简体   繁体   English

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

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

Does an update to static variable inside synchronized class method guarantee to have happens before? 在同步类方法中对静态变量的更新是否保证在之前发生? Use this as an example: 以此为例:

public class MyClass {
    private static boolean isDone = false;

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

        isDone = true;
    } 
}

Is variable isDone (without being volatile ) visible to all threads after getting updated inside this synchronized class method? 在此同步类方法中更新后,是否所有线程都可以看到变量isDone (没有volatile )? In my understanding, synchronization on MyClass.class itself makes no guarantee that all updates to its static variables are visible to other threads since other threads might have a local cache for it. 根据我的理解, MyClass.class同步本身并不能保证其静态变量的所有更新都对其他线程可见,因为其他线程可能有一个本地缓存。

happens-before is a relationship between two events. 发生 - 之前是两个事件之间的关系。 One of the event you pointed out: "update to static variable inside synchronized class method". 您指出的事件之一:“更新到同步类方法中的静态变量”。 What other event do you have in mind? 你有什么其他事件? Plain reading that variable in another thread? 普通读取另一个线程中的变量? No, plain reading in another thread does not participate in happens-before relationship. 不,在另一个线程中的普通阅读不参与发生在之前的关系。

That is, you are right suggesting synchronization makes no guarantee that all updates to variables are visible to other threads. 也就是说,您是正确的建议同步不保证所有变量更新对其他线程可见。

UPDT To guarantee that all updates to variables are visible to other threads, that threads also have to synchronize their reads, that is, make reading inside a synchronized class method. UPDT为了保证变量的所有更新对其他线程可见,该线程还必须同步它们的读取,即在同步类方法中进行读取。

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

After we exit a synchronized block, we release the monitor, which has the effect of flushing the cache to main memory, so that writes made by this thread can be visible to other threads. 在我们退出synchronized块之后,我们释放了监视器,它具有将缓存刷新到主内存的效果,因此该线程所做的写操作对其他线程是可见的。 Before we can enter a synchronized block, we acquire the monitor, which has the effect of invalidating the local processor cache so that variables will be reloaded from main memory. 在我们进入同步块之前,我们获取监视器,它具有使本地处理器高速缓存无效的效果,以便从主存储器重新加载变量。 We will then be able to see all of the writes made visible by the previous release. 然后,我们将能够看到前一版本中显示的所有写入。

Here is a simpler way of thinking about it that works if you follow good coding practice: 如果您遵循良好的编码实践,这是一种更简单的思考方式:

If it's synchronized you don't have to worry about it. 如果它是synchronized你不必担心它。

That's because, If thread A updates any variable and then releases a lock, the update will be visible to thread B after thread B locks the same lock, and if you follow good coding practice, then your synchronized blocks will be as small as possible: You won't be touching any shared variables inside the synchronized block that don't need synchronization. 这是因为,如果线程A更新了任何变量然后释放了一个锁,那么在线程B锁定相同的锁之后,线程B将看到更新, 如果你遵循良好的编码习惯,那么你的synchronized块将尽可能小:您不会触及同步块内不需要同步的任何共享变量。 And, if you follow good coding practice, then every access to the variable (write or read ) will be synchronized. 而且, 如果您遵循良好的编码习惯,那么对变量(写入或读取 )的每次访问都将被同步。

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

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