Thursday 6 October 2016

The Two Synchronized method Problem

The Two Synchronized method Problem.

Problem Statement: A class has two synchronized (non-static)methods M1 and M2. Two different threads T1 and T2 simultaneously trying to access the methods M1 and M2 respectively.
Is is possible?


import java.util.concurrent.TimeUnit;

public class TwoSyncMethods {

 public static void main(String[] args) {
  // TODO Auto-generated method stub

  
  final TwoSyncMethods tsm = new TwoSyncMethods();
  new Thread(new Runnable() {
   
   @Override
   public void run() {
    try {
     tsm.m1();
    } catch (InterruptedException e) {
     e.printStackTrace();
    }
   }
  }, "One").start();
  
   new Thread(new Runnable() {
   
   @Override
   public void run() {
    try {
     tsm.m2();//Calling other synchronized method on same object
    } catch (InterruptedException e) {
     e.printStackTrace();
    }
    
   }
  }, "Two").start();
  
 }

 public synchronized void m1() throws InterruptedException{
  System.out.println("Acquired by "+Thread.currentThread().getName());
  TimeUnit.SECONDS.sleep(2);  
  System.out.println("Released by "+Thread.currentThread().getName());
  
  
 }
  
 public synchronized void m2() throws InterruptedException
        {
   System.out.println("In Sync "+Thread.currentThread().getName());
   TimeUnit.SECONDS.sleep(5);
   System.out.println("In Sync After time out "+Thread.currentThread().getName());
  
 }
 
}

Answer. No,this is not possible.Two different methods can not access the two different synchronized method of the same class simultaneously.

Explanation : Every object has a monitor associated with it.For a thread to enter the synchronized block (also known as critical section), the thread must be the owner of the lock on the monitor. In other words, a thread must acquire a lock on the monitor if it wants to enter critical section.Now, since both the methods are non-static, therefore if they are called on the same object, the 1st thread, requesting the lock on monitor,will acquire the lock on the monitor while the 2nd thread will have to wait for lock to be released.

How to make it possible? As stated above, since same object is used to call both the methods, therefore once the lock is acquired by any one of the threads will cause the other thread to wait. So the solution to this to make two different objects of the class and then call the two methods simultaneously from the different threads using the different objects. This way, both the threads will acquire lock on the monitor of two different objects.


import java.util.concurrent.TimeUnit;

public class TwoSyncMethods {

 public static void main(String[] args) {
  // TODO Auto-generated method stub

  
  final TwoSyncMethods tsm1 = new TwoSyncMethods();
                final TwoSyncMethods tsm2 = new TwoSyncMethods();
  new Thread(new Runnable() {
   
   @Override
   public void run() {
    try {
     tsm1.m1();
    } catch (InterruptedException e) {
     e.printStackTrace();
    }
   }
  }, "One").start();
  
   new Thread(new Runnable() {
   
   @Override
   public void run() {
    try {
     tsm2.m2();//Calling synchronized methods on different objects
    } catch (InterruptedException e) {
     e.printStackTrace();
    }
    
   }
  }, "Two").start();
  
 }

 public synchronized void m1() throws InterruptedException{
  System.out.println("Acquired by "+Thread.currentThread().getName());
  TimeUnit.SECONDS.sleep(2);  
  System.out.println("Released by "+Thread.currentThread().getName());
  
  
 }
  
 public synchronized void m2() throws InterruptedException
        {
   System.out.println("In Sync "+Thread.currentThread().getName());
   TimeUnit.SECONDS.sleep(5);
   System.out.println("In Sync After time out "+Thread.currentThread().getName());
  
 }
 
}

What is the state of the thread waiting for other thread to exit critical section?
Blocked

public class StateCheck {

    public synchronized void m1() {
        try { Thread.sleep(2000); }
        catch (InterruptedException ie) {}
    }

    public synchronized void m2() {
        try { Thread.sleep(2000); }
        catch (InterruptedException ie) {}
    }

    public static void main(String[] args) throws InterruptedException {
        final StateCheck t = new StateCheck();
        Thread t1 = new Thread() { public void run() { t.m1(); } };
        Thread t2 = new Thread() { public void run() { t.m2(); } };

        t1.start();
        Thread.sleep(500);

        t2.start();
        Thread.sleep(500);

        System.out.println(t2.getState());
    }
}
A thread in the blocked state is waiting for a monitor lock to enter a synchronized block/method or reenter a synchronized block/method after calling Object.wait.

No comments:

Post a Comment