Cache flush on synchronized entry ,exit and volatile read and write

我们两清 提交于 2021-02-18 17:59:25

问题


When synchronized block execution is completed all the processor cache is flushed or only that object on which synchronized statement acted on will be flushed? In the below example when thread finished execution of method2 does data of obj2 is also flushed to the main memory?

class cls1 {
    int x=10;
}

class cls2{
    int y=10;
}

class cls3{
    cls1 obj1;
    cls2 obj2;
    public void method2(){
        obj2.y=10;
        synchronized(obj1){
            obj1.x=30;
        }
    }

    public static void main(String[] args) {
        final cls3 obj3 = new cls3();

        Thread thread1 = new Thread(){
            public void run(){
                obj3.method2();
            }
        };
        Thread thread2 = new Thread(){
            public void run(){
                System.out.println(obj3.obj1.x);
            }
        };
    }
}

回答1:


A happens before relation is established only when the other thread also synchronizes on the lock using which the first thread updated the contents.

In this example Thread B after acquiring the lock on same object M, it will be able to see all the changes that were made before and during the synchronized block. But mind that the lock must be acquired for happens-before relationship to occur.

In your example because System.out.println(obj3.obj1.x); is not printed inside a synchronized block, it does not guarantee happens before.

References:

  • http://www.ibm.com/developerworks/library/j-jtp03304/

EDIT: Excellent answer by Peter What is the scope of memory flushed or published to various threads when using volatile and synchronized?




回答2:


When synchronized block execution is completed all the processor cache is flushed or only that object on which synchronized statement acted on will be flushed?

Quick answer: all of the dirty blocks from the processor cache are flushed.

When a thread enters a synchronized block, it crosses a read memory-barrier which causes local copies of memory that have been updated in main memory to be flushed from the local processor memory cache.

When a thread exits a synchronized block, it crosses a write memory-barrier and all local processor dirty blocks are written to main memory. That's not just the lock object but all dirty memory blocks.

In the below example when thread finished execution of method2 does data of obj2 is also flushed to the main memory?

Yes. When the thread exits there is also a write memory barrier that is crossed.

System.out.println(obj3.obj1.x);

This probably will not print 30. It is important to realize that:

  • There is no guarantee in your code that thread2 will be running after thread1 completes. Even if you start thread2 after thread1, race conditions may have the thread2 access of obj1 happen before thread1 updates it or flushes the cache to central memory.
  • Also, even if you guarantee that the thread2 code does run after thread1 finishes, you will need to make sure that thread2 crosses a read memory barrier itself to read obj3 from main-memory and ensure that thread2 sees the memory updates from thread1. That would mean making obj3 be volatile or having thread2 also enter a synchronized block.

When you are sharing data between 2 threads it is necessary to make sure that you ensure proper order of operations and that the memory synchronization is taken into account.




回答3:


JLS doesn't speak about caches and their coherence, it uses 'happens-before' relation to establish ordering of inter-thread actions such as reads and writes to a shared memory. In your example, it's permitted to re-order obj2.y=10 so it goes after sync block. Plus, since there's no 'happens-before' established by method entry/exit, there's no guarantee from JMM that change will become visible after method finishes.

See "Java memory model" of Java spec for detailed explanation of underlying principles.

Btw, seems you forgot to call start() method on thread instances you've created in main.



来源:https://stackoverflow.com/questions/38994749/cache-flush-on-synchronized-entry-exit-and-volatile-read-and-write

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!