6

I need some clarification with regards to use of synchronization in multi-threaded environment. I have a small example Class below. but I am actually finding it hard to make a test case of how the following will work; The reason I want test case is to the understand how synchronization handles these different scenarios


  • If a thread calls SharedResource.staticMethod, it will acquire the lock for the class. does it mean an instance of SharedResource, say x, will have to wait till it gets lock to exectute x.staticMethod.

  • Will synchronization of this in a block, acquires the lock for that section of the code or for entire object. i.e can another thread call the same method on same object; but execute the remainder of the code that is not part of synchronization block

  • If the above point is true, having a dummy object to lock on does not provide any additional benefit. Correct?

  • So there are different levels of synchronziations. Class level, Object level, method level and block level. so that would mean locks for these individual levels should exist? If I acquired a lock on the Object, another Thread cannot call any methods on the same object, but if I acquired a lock on the method, another thread can acquire lock on a different method. Is this correct?

Some tips on on how to create two threads that act on same object and same method will be helpful (I understand I need to extend Thread class or implement Runnable interface). But not sure how to make a two threads call the same method on same object.

class SharedResource {
     public Integer x =0;
     public static Integer y=0;
     Object dummy = new Object();
     public Integer z=0;

     public synchronized static void staticMethod(){
         System.out.println("static Method is called");
         y++; 
     }

     public synchronized void incrementX(){
         System.out.println("instance method; incrementX");
         x++;
     }

     public void incrementXBlock(){
         synchronized(this){
             x++;
         }
         System.out.println("instance method; incrementXBlock");
     }

     public void incrementZ(){
         synchronized (dummy) {
             z++;
         } 
         System.out.println("synchronized on dummy; incrementZ method ");
     }
}

public class ThreadSynchronization extends Thread {

}

I have read these posts, but I am not positive if I understood it clearly.

Java synchronized method lock on object, or method?, Does java monitor include instance variables?

Community
  • 1
  • 1
eagertoLearn
  • 9,772
  • 23
  • 80
  • 122
  • There is also good article about java synchronization http://javarevisited.blogspot.com/2011/04/synchronization-in-java-synchronized.html – RMachnik Feb 26 '14 at 19:44
  • There is only one type of synchronization and that's on an object. Where and how the synchronized is used determines which object that is. – Sotirios Delimanolis Feb 26 '14 at 19:47
  • Java runs in the way of monitors. So when you synchronize object objectA, and objectB there is different lock acquired. – RMachnik Feb 26 '14 at 19:48
  • @SotiriosDelimanolis: http://docs.oracle.com/javase/tutorial/essential/concurrency/locksync.html mentions that "When a thread invokes a synchronized method, it automatically acquires the intrinsic lock for that method's object and releases it when the method returns." does that mean a lock for method exists? – eagertoLearn Feb 26 '14 at 19:50
  • 1
    @eagertoLearn It says `that method's object`. An instance method is invoked on an object. The thread will acquire that object's monitor. There is no such thing as a method lock. – Sotirios Delimanolis Feb 26 '14 at 19:51
  • @SotiriosDelimanolis: so that would prevent another thread from executing other methods of the same object..correct? that would be inefficient correct? – eagertoLearn Feb 26 '14 at 19:52
  • No, nothing **ever** prevents another thread from executing a method. If that other thread tries to execute a block of code synchronized on the same object, then it will wait until that other thread has released the monitor. – Sotirios Delimanolis Feb 26 '14 at 19:54
  • @SotiriosDelimanolis: I see, although Thread1 has acquired the lock for the object, it basically locks up the syncronized blocks in the that object, so other part is free for other threads to access? – eagertoLearn Feb 26 '14 at 19:56
  • There is just synchronizing on the class, and synchronizing on the object, and when a synchronized method is called it waits until it gets an exclusive lock on the object before proceeding. There are not different locks for different methods of an object, or for sections of code within a method. They just lock the object they are part of. – David Conrad Feb 26 '14 at 19:57
  • I want to say yes, but I'm worried you are making other assumptions. [Read this tutorial.](http://docs.oracle.com/javase/tutorial/essential/concurrency/sync.html) – Sotirios Delimanolis Feb 26 '14 at 19:58

1 Answers1

4
class SharedResource {
  public synchronized static void staticMethod(){
    System.out.println("static Method is called");
    y++; 
  }
  public synchronized void incrementX(){
     System.out.println("instance method; incrementX");
     x++;
  }
}

does the same as

class SharedResource {
  public static void staticMethod(){
    synchronized(SharedResource.class) {
      System.out.println("static Method is called");
      y++;
    }
  }
  public void incrementX(){
    synchronized(this) {
      System.out.println("instance method; incrementX");
      x++;
    }
  }
}

Simply said, a thread entering a synchronized block will acquire a lock on the specified object for the duration of the block. This implies that at most one thread can execute a synchronized code block for a particular lock object. Since the Class instance and a particular instance of that class are different object, synchronized static methods and synchronized instance methods do not block each other. But there is no difference between “method level” and “block level”; the important point is which object is chosen for the synchronization.

Holger
  • 285,553
  • 42
  • 434
  • 765
  • Thanks for the explanation. I would like to test some of these, how can I create a two threads that act on same objects and call same methods? the last point of in my question – eagertoLearn Feb 26 '14 at 19:58
  • See http://docs.oracle.com/javase/tutorial/essential/concurrency/index.html Section “Defining and Starting a Thread” or “The SimpleThreads Example” – Holger Feb 27 '14 at 09:13