Monday, September 5, 2016

JAVA MULTITHREADING: Thread Synchronization using 'synchronized' keyword

So imagine a situation where a single primitive type variable is being accessed concurrently by two different threads.

Here, the final value of the 'count' variable is supposed to reach 20000 at last. But it won't!

NOT without the use of  'synchronized' keyword. It can be used ONLY WITH METHODS!


Taken from a verified answer on StackOverflow:
Synchronized methods enable a simple strategy for preventing thread interference and memory consistency errors: if an object is visible to more than one thread, all reads or writes to that object's variables are done through synchronized methods.

In a very, very small nutshell: When you have two threads that are reading and writing to the same 'resource', say a variable named foo, you need to ensure that these threads access the variable in an atomic way. Without the synchronized keyword, your thread 1 may not see the change thread 2 made to foo, or worse, it may only be half changed. This would not be what you logically expect.

*******************************************************************************

The output of the below code will be 20000.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
public class App {
 
 private int count = 0;
 private synchronized void increment(){
  count++;
 }
 
 public void doWork(){
  Thread t1 = new Thread(new Runnable(){
   public void run(){
    for(int i=0; i<10000; i++){
     increment();
     System.out.println("Inside 1");
    }
   }
  });
  
  Thread t2 = new Thread(new Runnable(){
   public void run(){
    for(int i=0; i<10000; i++){
     increment();
     System.out.println("Inside 2");
    }
   }
  });
  
  t1.start();
  t2.start();
  
  try {
   t1.join();// <-- This makes main() wait until t1 is done running
   t2.join();// <-- After t1 thread completes execution, t2 makes it wait until it's done
   /**
    * It is to be noted that t1 and t2 have been running parallely and do not affect the
    * execution of one another. They only pause the execution of the method from which they
    * are called.
    */
  } catch (InterruptedException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
  System.out.println("Count is " + count);
 }
 
 public static void main(String[] args){
  App app = new App();
  app.doWork();
 }
}

No comments:

Post a Comment