Synchronization
Synchronization is the capability of control the access of multiple threads to any shared resource. Synchronization is better in case we want only one thread can access the shared resource at a time.
Synchronization in Java is an important concept since Java is a multi-threaded language where multiple threads run in parallel to complete program execution. In multi-threaded environment synchronization of java object or synchronization of java class becomes extremely important. Synchronization in Java is possible by using java keyword “synchronized” and “volatile”. Concurrent access of shared objects in Java introduces to kind of errors: thread interference and memory consistency errors and to avoid these errors you need to properly synchronize your java object to allow mutual exclusive access of critical section to two threads.
Why use Synchronization?
The synchronization is mainly used to
If your code is executing in multi-threaded environment you need synchronization for objects which are shared among multiple threads to avoid any corruption of state or any kind of unexpected behavior. Synchronization in Java will only be needed if shared object is mutable. if your shared object is read only or immutable object you don’t need synchronization despite running multiple threads. Same is true with what threads are doing with object if all the threads are only reading value then you don’t require synchronization in java. JVM guarantees that Java synchronized code will only be executed by one thread at a time.
1) synchronized keyword in java provides locking which ensures mutual exclusive access of shared resource and prevent data race.
2) synchronized keyword also prevent reordering of code statement by compiler which can cause subtle concurrent issue if we don’t use synchronized or volatile keyword.
3) synchronized keyword involve locking and unlocking. before entering into synchronized method or block thread needs to acquire the lock at this point it reads data from main memory than cache and when it release the lock it flushes write operation into main memory which eliminates memory inconsistency errors.
Types of Synchronization:
There are two types of synchronization
Here, we will discuss only thread synchronization.
Thread Synchronization:
There are two types of thread synchronization mutual exclusive and inter-thread communication.
Mutual Exclusive
Mutual Exclusive helps keep threads from interfering with one another while sharing data. This can be done by three ways in java:
Understanding the concept of Lock
Synchronization is built around an internal entity known as the lock or monitor.Every object has an lock associated with it. By convention, a thread that needs consistent access to an object’s fields has to acquire the object’s lock before accessing them, and then release the lock when it’s done with them.
From Java 5 the package java.util.concurrent.locks contains several lock implementations.
Understanding the problem without Synchronization:
In this example, there is no synchronization, so output is inconsistent. Let’s see the example:
class First { public void display(String msg) { System.out.print ("["+msg); try { Thread.sleep(500); } catch(InterruptedException e) { e.printStackTrace(); } System.out.println ("]"); } } class Second extends Thread { String msg; First fobj; Second (First fp,String str) { fobj = fp; msg = str; start(); } public void run() { fobj.display(msg); } } public class WithoutSyncDemo { public static void main (String[] args) { First fnew = new First(); Second ss = new Second(fnew, "welcome"); Second ss1 = new Second (fnew,"to"); Second ss2 = new Second(fnew, "dineshonjava.com"); } }
Output:
In the above program, object fnew of class First is shared by all the three running threads(ss, ss1 and ss2) to call the shared method(void display). Hence the result is unsynchronized and such situation is called Race condition.
Solution by synchronized method:
class First { public synchronized void display(String msg) //synchronized method { System.out.print ("["+msg); try { Thread.sleep(500); } catch(InterruptedException e) { e.printStackTrace(); } System.out.println ("]"); } } class Second extends Thread { String msg; First fobj; Second (First fp,String str) { fobj = fp; msg = str; start(); } public void run() { fobj.display(msg); } } public class WithoutSyncDemo { public static void main (String[] args) { First fnew = new First(); Second ss = new Second(fnew, "welcome"); Second ss1 = new Second (fnew,"to"); Second ss2 = new Second(fnew, "dineshonjava.com"); } }
output:
Solution by synchronized block:
class First { public void display(String msg) { System.out.print ("["+msg); try { Thread.sleep(500); } catch(InterruptedException e) { e.printStackTrace(); } System.out.println ("]"); } } class Second extends Thread { String msg; First fobj; Second (First fp,String str) { fobj = fp; msg = str; start(); } public void run() { synchronized(fobj){ //Synchronized block fobj.display(msg); } } } public class WithoutSyncDemo { public static void main (String[] args) { First fnew = new First(); Second ss = new Second(fnew, "welcome"); Second ss1 = new Second (fnew,"to"); Second ss2 = new Second(fnew, "dineshonjava.com"); } }
output:
Synchronized Keyword:
To synchronize above program, we must synchronize access to the shared display() method, making it available to only one thread at a time. This is done by using keyword synchronized with display() method.
synchronized void display (String msg)
Strategy Design Patterns We can easily create a strategy design pattern using lambda. To implement…
Decorator Pattern A decorator pattern allows a user to add new functionality to an existing…
Delegating pattern In software engineering, the delegation pattern is an object-oriented design pattern that allows…
Technology has emerged a lot in the last decade, and now we have artificial intelligence;…
Managing a database is becoming increasingly complex now due to the vast amount of data…
Overview In this article, we will explore Spring Scheduler how we could use it by…