The main problem(s) we meet with a multithreaded code is sharing data, and I agree with, the purpose of concurency parallizing process and it happens "ofently" that during parallalized processing that threads need accessing for read/write on shared data.
The java synchronized keyword permits the following:
It tells the JVM to put a lock on the monitor of the object or the piece of the synchronized code, which gives it exclusive access to that part of code or object.
Here's an example of a Singleton:
public class Singleton {
private Singleton INSTANCE;
private Singleton() {
}
public Singleton getInstance() {
if (null == INSTANCE) {
INSTANCE = new Singleton();
}
return INSTANCE;
}
}
This Singleton is not thread safe, if a thread is trying to get an instance while another is also trying to do the same (race condition) it may happen that before that the thread number one finishes the creation of the instance the second has already had access to the getInstance()
method and created his own instance of the Singleton which means that at a T time we should have two instances of the Singleton (called multiton at that time).
To solve this problem we have to synchronize the creational behaviour of the singleton, this may be done by the keyword synchronized
above the if statement on the INSTANCE
itself:
public class Singleton {
private Singleton INSTANCE;
private Singleton() {
}
public Singleton getInstance() {
synchronized (Singleton.class) {
if (null == INSTANCE) {
synchronized(Singleton.class) {
Singleton inst = new Singleton();
INSTANCE = inst;
}
}
}
return INSTANCE;
}
}
The result is when the first thread asks the Singleton instance and during creation time, the JVM will put a lock on the monitor of the INSTANCE denying any access to the INSTANCE until thread one finished its request.
There are diffrent ways to achieve that as well, the book cited before is an excellent source of learning, javadoc also.