Volatile and Synchronized
Asked Answered
I

4

5

There is something i haven't yet understand about synchronized and volatile.

I understand that a thread can safe changes locally. From what i have read so far is that synchronized > volatile.

Say i have an parameter which is not long or double so basically a standard Integer ( no atomic ).

And i have a synchronized method where i do a lot work with this Integer. Will all threads get the updated version of this Integer? Or do i have to declare it volatile as well?

public class stackoverflow {

    private int x = 0;

    public synchronized void rechnen(){ 
        //dosomething   
    }
}

basically after rechnen() is done, and i got 10000 threads, will all get the updates version of x because my method is synchronized? or do i have to declare it volatile as well?

Isocyanide answered 30/12, 2015 at 10:32 Comment(1)
Please tag your questions with the programming language you are using.Furry
S
6

Yes, they will get updated version. synchronized guarantees two things: visibility of changes and atomicity. volatile just guarantees visibility of changes. Java guarantees that code inside synchronized block will not be optimized (by mixing commands inside and outside the synchronized block) so every change on variables inside it, will be visible to all threads after the end of synchronized block.

Siberson answered 30/12, 2015 at 10:36 Comment(3)
"every changes on variables inside it will be visible to all thread after end of synchronized block" this is correct of course, but, I think, this is not correct "Java guarantees that code inside synchronized block will not be optimized".Richmal
@Richmal yes you are right. I didn't write that well. I edited the answer. What I was thinking is that Java will not optimize code by mixing statements inside and outside the synchronized block.Siberson
...every change on variables inside it, will be visible to all threads after the end of synchronized block. Not completely true. The JLS only guarantees that if thread A updates a variable and then exits a synchronized block, then thread B will be able to see the update after thread B synchronizes on the same object.Charybdis
R
5

@partlov already answered your question so as a side note there are some other things you might want to consider.

Don't use synchronized as a modifier

when declaring a method as synchronized it uses a monitor. In Java every Object happens to be a monitor and in this case the class instance is used. So your example affectively becomes:

public void rechnen(){ 
    synchronized(this) {
        //dosomething
    }   
}

Now this poses a potential problem because you are leaking your monitor. Other parts of your application can use this same monitor to synchronize completely unrelated code which can lead/ leads to performance degradation, or worse, when it is related it can lead to unexpected deadlocks.

So the main advice is, to always keep your monitors private. So something like:

public class stackoverflow {
    private final Object monitor = new Object();
    private int x = 0;

    public void rechnen(){
         synchronized(monitor) {
            //dosomething
         } 
    }
}

know your Api

Between volatile and synchronized there is a plethora of tools for specific concurrency purposes. Most of which use a mix of volatile, synchronized and CAS-operations. For instance AtomicInteger gives you atomic integer operation with far less contention as is usually seen by the of synchronized. So try to get really familiar with java.util.concurrent

Raimes answered 30/12, 2015 at 11:20 Comment(0)
D
3

Yes, they will get the updated version, but only if they enter a synchronized block themselves. If they do not enter a synchronized block on the same object (lock the same monitor) then it is not guaranteed they will see the updates.

If you don't want other threads to enter the synchronized block, then you have to declare the variable as volatile.

Despatch answered 30/12, 2015 at 11:12 Comment(1)
It doesn't have to be the same synchronized block. It does have to be a block that synchronizes on the same lock object.Charybdis
L
-2

Declare private volatile int x = 0; it will serve your purpose. For better understanding see the implementation of AtomicInteger .

Litigate answered 30/12, 2015 at 11:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.