Synchronization in Java can be thought of as a queue at a ticketing counter where a number of customers are waiting for the current customer to finish. As soon as the current customer gets their ticket, all the other customers move one position closer to the ticket counter.
Synchronization deals with threads in the same way as a ticketing counter. Threads allow multiple processes to be conducted in multiple ways.
Suppose a process adds and multiplies a particular array of elements – two threads can be used to implement this, one can be used to multiply, and the other can perform addition. This allows less CPU usage and saves a lot of CPU time.
Synchronization, in particular, is a concept that ensures that exactly one thread is entertained at a time (i.e., multiple threads do not function at the same time).
Synchronization allows a programmer to perform concurrent programming and prevents data corruption. It can be better understood by the following example:
int a = 5;
int b = 4;
int c = 0;
c = a + b;
c = c * a;
Suppose that two threads exist. Thread one performs c = a + b
while thread two performs c = c * a;
.
Initially c=0
, so what if thread two gets the cpu time before thread one? The value of c
will remain zero despite the multiplication with a
. The original answer should have been 9=5+4
and then 45=9*5
(i.e., c=45
). However, if thread two occurs before thread one, the answer would be 0=0*5
and then 9=5+4
(i.e., c=9
).
Synchronization in Java could be simplified by adding the Synchronized
keyword, which is placed before defining a method. The two codes ahead will represent how synchronization works.
The output of this code will be in random order. This will be fixed (later) with synchronization.
class Array{void printNumbers(int n){//method not synchronizedfor(int i=1;i<=3;i++){System.out.println(n*i);try{Thread.sleep(500); //delayed a thread by 500 ms}catch(Exception e){System.out.println(e);}}}}class MyThread1 extends Thread{Array a;MyThread1(Array a){this.a=a;}public void run(){a.printNumbers(1);}}class MyThread2 extends Thread{Array a;MyThread2(Array a){this.a=a;}public void run(){a.printNumbers(10);}}class main{public static void main(String args[]){Array myArr = new Array();//only one objectMyThread1 t1=new MyThread1(myArr);MyThread2 t2=new MyThread2(myArr);t1.start();t2.start();}}
Notice the difference in output between the code without synchronization (above) and the code with synchronization (below).
The t1
thread is fully completed before t2
starts.
class Array{synchronized void printNumbers(int n){//method synchronizedfor(int i=1;i<=3;i++){System.out.println(n*i);try{Thread.sleep(500); //delayed a thread by 500 ms}catch(Exception e){System.out.println(e);}}}}class MyThread1 extends Thread{Array a;MyThread1(Array a){this.a=a;}public void run(){a.printNumbers(1);}}class MyThread2 extends Thread{Array a;MyThread2(Array a){this.a=a;}public void run(){a.printNumbers(10);}}class main{public static void main(String args[]){Array myArr = new Array();//only one objectMyThread1 t1=new MyThread1(myArr);MyThread2 t2=new MyThread2(myArr);t1.start();t2.start();}}