Avoiding deadlocks with Reentrantlock

This post showed how multiple threads synchronizing on two resources in different order usually leads to a deadlock. An obvious solution is to arrange for all threads to acquire locks in the same order.

Alternatively the synchronized blocks can be replaced by reentrant locks. The tryLock method of the ReentrantLock class is used to acquire a lock, returning immediatly if that lock is held by another thread (and not blocking forever as would be the case when using synchronized).

Example follows – livelock issues not dealt with at this point (ie. both threads, whilst not being blocked, may still not get any job done as they keep colliding when trying to acquire locks).

import java.util.concurrent.locks.ReentrantLock;

public class LockAcquisition {

	public static void main (String args[]){

		final ReentrantLock lockA = new ReentrantLock();
		final ReentrantLock lockB = new ReentrantLock();

		new Thread() {
			public void run (){
				while (1==1) {
					try {
						System.out.println (this + " acquiring lockA");
						if (lockA.tryLock()) {
							System.out.println (this + " acquired lockA");
							System.out.println (this + " acquiring lockB");
							if (lockB.tryLock()){
								System.out.println (this + " acquired lockB");
							}
						}
					}
					finally {
						if (lockB.isHeldByCurrentThread()) lockB.unlock();
						if (lockA.isHeldByCurrentThread()) lockA.unlock();
					}
				}
			}
		}.start();

		new Thread() {
			public void run (){
				while (1==1) {
					try {
						System.out.println (this + " acquiring lockB");
						if (lockB.tryLock());
							System.out.println (this + " acquired lockB");
							System.out.println (this + " acquiring lockA");
							if (lockA.tryLock()){
								System.out.println (this + " acquired lockA");
							}
					}
					finally {
						if (lockA.isHeldByCurrentThread()) lockA.unlock();
						if (lockB.isHeldByCurrentThread()) lockB.unlock();

					}
				}
			}
		}.start();
	}
}

Advertisements

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