Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Volatile and Synchronized

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?

like image 998
Timo N. Avatar asked Jan 07 '23 22:01

Timo N.


2 Answers

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.

like image 192
partlov Avatar answered Jan 15 '23 12:01

partlov


@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

like image 33
M Platvoet Avatar answered Jan 15 '23 13:01

M Platvoet