Suggested Pages

Monday, February 25, 2013

Implicit Lock : Object Lock and Class Lock

Both Object Locks and Class Locks are called implicit locks because the developer hasn't to create a lock object explicitly.

Object Lock


In Java an implicit lock is associated with each object and it is used to synchronize threads on the object's state. The object that has to synchronize thread accesses to its state, it's called: Monitor. To perform synchronization using implicit object lock, developers have to use the synchronized keyword on instance methods.
Simply when a thread calls a synchronized method of an object, it has to acquire the object lock. Suppose a thread t1 tries to call a synchronized method, it tries to acquire the object lock. If another thread t2 tries to call a synchronized methods on the same object, it has to acquire the same object lock. if the lock was acquired by the thread t1, the thread t2 must wait until the thread t1 will release the lock.
In the following code we'll see an example of a Monitor (Monitor.java) that has an instance variable counter. This variable represents a shared variable for the threads MyThread. In order to avoid interference among threads it has been used implicit object lock of Monitor object.

Monitor.java

public class Monitor {

 private int counter;

 public synchronized int getCounter() {
  System.out.println("getCounter():"+counter);
  return counter;
 }

 public synchronized void setCounter(int counter) {
  System.out.println("setCounter():"+counter);
  this.counter = counter;
 }
  
}

As you can see the thread shown below tries to access to the Monitor state using getCounter() and setCounter() methods. These methods protect the so called Critical Region, preventing these two threads to access the monitor instance variable at the same time. Monitor methods use an intrinsic reentrant lock because the thread that has acquired the object lock, can still acquire the same lock even if it has not released the previus lock acquired.

MyThread.java
package com.simonefolinoblogspot.synchronization;

public class MyThread extends Thread {

 private Monitor monitor;
 
 public MyThread(Monitor monitor) {
  this.monitor = monitor;
 }

 @Override
 public void run() {
     int counter = monitor.getCounter();
     counter++;
     monitor.setCounter(counter);
 }
 
}



Main.java
package com.simonefolinoblogspot.synchronization;

public class Main {

 public static void main(String[] args) {

  Monitor monitor=new Monitor();
  MyThread t1=new MyThread(monitor);
  MyThread t2=new MyThread(monitor);
  t1.start();
  t2.start();
 }
}



Class Lock


While there is a lock object for each objects, class lock is only one for a class. It acts at the same way as Object Lock from the acquiring point of view.

Synchronized Statements


Another way to create synchronized code is to use a block synchronized . This mechanism allows developers to explain the object of which is to acquire the lock.
In the following code you can see the previus Monitor implemented by Synchronized Statements.
Monitor.java
package com.simonefolinoblogspot.synchronization;

public class Monitor {

 private int counter;

 public  int getCounter() {
  synchronized(this){
      System.out.println("getCounter():"+counter);
  }
  return counter;
 }

 public  void setCounter(int counter) {
  synchronized(this){
    System.out.println("setCounter():"+counter);
    this.counter = counter;
  }

 }
  
}


About Synchronization


  • Implicit Object Lock are Reentrant Lock
  • Only static and instance method can use synchronized keyword
  • Constructors can't be synchronized : Only the thread that creates the object should access it during inizialization. Developers should take care on not leaving references to that object before completion

Suggested Pages