5

When a synchronized method is completed, will it push only the data modified by it to main memory, or all the member variables, similarly when a synchronized method executes, will it read only the data it needs from main memory or will it clear all the member variables in the cache and read their values from main memory ? For example

public class SharedData
{

    int a; int b; int c; int d;

    public SharedData()
    {
        a = b = c = d = 10;
    }

    public synchronized void compute()
    {
        a = b * 20;
        b = a + 10;
    }

    public synchronized int getResult()
    {
        return b*c;
    }

}

In the above code assume compute is executed by threadA and getResult is executed by threadB. After the execution of compute, will threadA update main memory with a and b or will it update a,b,c and d. And before executing getResult will threadB get only the value of b and c from main memory or will it clear the cache and fetch values for all member variables a,b,c and d ?

Karthik
  • 335
  • 3
  • 11

3 Answers3

3

synchronized ensures you have a consistent view of the data. This means you will read the latest value and other caches will get the latest value. Caches are smart enough to talk to each other via a special bus (not something required by the JLS, but allowed) This bus means that it doesn't have to touch main memory to get a consistent view.

Peter Lawrey
  • 513,304
  • 74
  • 731
  • 1,106
  • 2
    thanks. Then why we need volatile key word in Java ? Please check this link [link](http://www.ibm.com/developerworks/java/library/j-jtp06197/index.html) – Karthik Aug 01 '12 at 04:10
  • 1
    If you only use synchronized, you wouldn't need volatile. Volatile is useful if you have a very simple operation for which synchronized would be overkill. – Peter Lawrey Aug 01 '12 at 14:26
  • @PeterLawrey Sir, I have some related doubt abput synchronized block , Would be really helpful if you could enlighten me about my question : http://stackoverflow.com/q/42163468/504133 – nits.kk Feb 10 '17 at 16:08
  • 1
    @nits.kk The answer to your question is; yes. synchronized reads don't mean anything without synchronized writes. – Peter Lawrey Feb 10 '17 at 18:48
  • @PeterLawrey Thanks , I feel I have understood, at least for the time being, will trouble more with further questions If I fail to discover the answers :) Thanks a lot for the help .. – nits.kk Feb 10 '17 at 18:52
  • @PeterLawrey "synchronized ensures you have a consistent view of the data. " so is the read barrier ensures to read the data even though the synchronize has been done on different object ? eg. : public class SharedData { int a; int b; int c; int d; public SharedData(Object x) { synchronized (x){....}; // is a,b,c,d are consistent here ? } – Mohammad Karmi Oct 13 '18 at 14:54
  • 1
    @MohammadKarmi consistent for read only, yes. you can't do read/write atomically if you use more than one lock. i.e. you get no more guarantee than volatile. – Peter Lawrey Oct 13 '18 at 15:13
2

I think following thread should answer your question.

Memory effects of synchronization in Java

In practice, the whole cache is not flushed.

Community
  • 1
  • 1
sgp15
  • 1,240
  • 8
  • 13
  • thanks I went through the link given by you. They have concluded that full flush will not happen. But its based on their assumption, they don’t refer to any proof. Is their any jvm spec which confirms full cache flush will not happen ? – Karthik Jul 31 '12 at 06:26
  • Apologies for late reply. JVM specs just define a contract. The implementations normally don't provide details. Lastly, its expensive to flush the whole cache. Therefore, logically, implementations go with optimizations where ever possible. – sgp15 Aug 03 '12 at 13:44
1

1. synchronized keyword on a method or on an atomic statement, will lock the access to the resource that it can modify, by allowing only one thread to gain the lock.

2. Now preventing of caching of values into the variables is done by volatile keyword. Using volatile keyword will ask the JVM to make the thread that access the instance variable to reconcile its copy of the instance variable with the one saved in the memory.

3. Moreover in your above example, if threadA execute the compute(), then threadB canNot access the getResult() method simultaneously, as they both are synchronized methods, and only one thread can have access to the all the synchronized methods of the object, cause its not the method that is locked but the Object. Its like this... Every object has one lock, and the thread which wants to access its synchronized block must get that lock

4. Even every class has a lock, that is used to protect the crucial state of the static variables in the class.

Kumar Vivek Mitra
  • 32,904
  • 6
  • 47
  • 76
  • my question was not regarding lock, my question was regarding the memory model, how the values are getting sync with main memory from cache during synchronized method execution. – Karthik Jul 31 '12 at 05:47
  • During the synchronized process there is no sync mechanism...its simply like this.. When A thread alters the state of an crucial data, no other thread can access that data, once thread A is done with and the lock is released, then the other thread B can read it and write it, and at this time thread A canNot access that state of the data. Cache prevention mechanism is done when volatile keyword is used... thats what i tried to explain in my answer.... – Kumar Vivek Mitra Jul 31 '12 at 07:15
  • thanks. Assume the code is running in multiprocessor environment, and threadA is executing in processor 1 and threadB is executing in processor 2. Assume both threads have cached the SharedData instance (as in above example) locally in processor cache. At time t1, threadA executes compute() method and releases the lock. After some time t1+delta (no lock on the instance), threadB executes getResult() method.Now threadB needs to refresh the processor cache for the member values of SharedData instance before executing the getResult(). What member variables gets refreshed (b&c or all) ? – Karthik Aug 01 '12 at 04:08