Home > Multithreading > Java Multithreading – External Locks

Java Multithreading – External Locks


You must be aware with the need of synchronization after reading Bad synchronization leads program’s death and Synchronization – solve the mystery.

Well! synchronized has some limitations. Lets understand with this example.

 

public class DummyClass {
	private Integer age = 0;
	public void display(){
		System.out.println(Thread.currentThread().getName() + ": " + age);
	}
	public void edit(int n){
		age = n;
	}
}

public class SynchronizedLimitDemo {

	public static void main(String[] args) {
		final DummyClass dcObj = new DummyClass();
		Thread amit = new Thread(new Runnable(){
				@Override
				public void run() {
					try{
						dcObj.edit(27);
						Thread.sleep(1000);
						dcObj.display();
					}catch(InterruptedException ixp){
						System.out.println(ixp.getMessage());
					}
				}
			},"Amit Thread");

		Thread arti = new Thread(new Runnable(){
				@Override
				public void run() {
					try{
						dcObj.edit(29);
						Thread.sleep(1000);
						dcObj.display();
					}catch(InterruptedException ixp){
						System.out.println(ixp.getMessage());
					}
				}
			},"Arti Thread");

		amit.start();
		arti.start();
	}
}

In above stupid example, even if you synchronized display() & edit(), you can’t get proper output. Now see how external locking (since Java 5) can solve it.

public class DummyClass {
	private Integer age = 0;
	private Lock dataLock = new ReentrantLock();
	public void display(){
		System.out.println(Thread.currentThread().getName() + ": " + age);
		dataLock.unlock();
	}
	public void edit(int n){
		dataLock.lock();
		age = n;
	}
}

Output:
Arti Thread: 29
Amit Thread: 27

Warning: If a thread tries calling display() directly or before lock was acquired, it’ll generate run time exception. Similarly a thread can call edit() multiple times but can forget calling display(). It’ll lock the object forever.
This example is just to elaborate an advantage of Lock over synchronized.

Problem with synchronized keyword

  1. A synchronized block makes no guarantees about the sequence in which threads waiting to entering it are granted access.
  2. You cannot pass any parameters to the entry of a synchronized block. Thus, having a timeout trying to get access to a synchronized block is not possible.
  3. The synchronized block must be fully contained within a single method. It’s not possible that synchronization starts in one method and ends in another.
  4. If a thread meets synchronized block, where another thread already had entered into it, it is supposed to wait until another thread release the lock.

Java 5 provides another locking mechanism. Where

  1. A thread can request to acquire a lock with timeout period. If lock is not acquired then thread can do something else or can request again.
  2. A Lock can be started in one method and can end in another.
How to

synchronized


method(
	synchronized(this){
		//critical section
	}
}

Lock

Lock lock = new ReentrantLock();

method(
	lock.lock();
	//critical section
	lock.unlock();
}

* It is good to call unlock() in finally block.

 

Methods

The Lock interface has the following primary methods:

  • lock()
  • lockInterruptibly()
  • tryLock()
  • tryLock(long timeout, TimeUnit timeUnit)
  • unlock()

The lock() method locks the Lock instance if possible. If the Lock instance is already locked, the thread calling lock() is blocked until the Lock is unlocked.

The lockInterruptibly() method locks the Lock unless the thread calling the method has been interrupted. Additionally, if a thread is blocked waiting to lock the Lock via this method, and it is interrupted, it exits this method calls.

The tryLock() method attempts to lock the Lock instance immediately. It returns true if the locking succeeds, false if Lock is already locked. This method never blocks.

The tryLock(long timeout, TimeUnit timeUnit) works like the tryLock() method, except it waits up the given timeout before giving up trying to lock the Lock.

The unlock() method unlocks the Lock instance. Typically, a Lock implementation will only allow the thread that has locked the Lock to call this method. Other threads calling this method may result in an unchecked exception (RuntimeException).

Note:
If you have locked an object N times you will have to call unlock() N times.

Advertisements
Categories: Multithreading
  1. No comments yet.
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: