Theads Deadlock Example in Java

Connect with

Deadlock describes a situation where two or more threads are blocked forever, waiting for each other. You know , order of execution of threads are non-deterministic, so sometimes very difficult to reproduced deadlock situation , sometimes very hard to come out of deadlock situation, so be careful while locking order on multiple object by multiple threads.

Key Point about deadlock

  • Deadlocks can arise in the context of multiple locks.
  • If multiple locks are acquired in the same order, then a deadlock will not occur. However, if
    you acquire them in a different order, then deadlocks may occur.
  • Deadlocks are non-deterministic, you cannot consistently reproduce deadlocks.

Avoid acquiring multiple locks. If you want to acquire multiple locks, make sure that they are acquired in the same order everywhere to avoid deadlocks.

Deadlock with Example

The following example tried to reproduced to deadlock condition but not produced the same result every time. For simplicity and easy to understand , I tried to write comment on code itself.


/**
 * @author ranjeet.jha
 *
 */
public class DeadLockExample {
		
	public static void main(String args[]) throws InterruptedException {
		CounterRunnable c = new CounterRunnable();
		
		// create two threads and start them at the same time
		Thread t1 = new Thread(c);
		Thread t2 = new Thread(c);
		t1.start();
		t2.start();
		
		System.out.println("Waiting... for threads to complete execution.");
		t2.join();
		t2.join();
		
		System.out.println("successfully executed , no deadlock situation.");
	}
}

/**
 * This Ball class has a globally accessible variable to hold the number of BALL_COUNTER.
 * 
 * @author ranjeet.jha
 *
 */
class Ball {
	public static long BALL_COUNTER = 0;
}

/**
 * This Run class has a globally accessible variable to hold the number scored.
 * 
 * @author ranjeet.jha
 *
 */
class Run {
	public static long RUN_COUNTER = 0;
}

/**
 * CounterRunnable is a thread class , having two methods – 
 *  - IncrementBallAfterRun and 
 *  - IncrementRunAfterBall
 * For demonstrating deadlock, we call these two methods in the run method, 
 * so that locking can be requested in opposite order in these two methods.
 * 
 * @author ranjeet.jha
 *
 */
class CounterRunnable implements Runnable {

	public void run() {
		
		/*
		 * call these two methods (incrementBallAfterRun and incrementRunAfterBall) which acquire locks 
		 * in different order depending on  thread scheduling and the order of lock acquisition 
		 * which may or may not a deadlock. 
		 */
		incrementBallAfterRun();
		incrementRunAfterBall();
	}

	/**
	 * This method user to get increments RUN_COUNTER variable first and then increments the BALL_COUNTER variable 
	 * since these variables are accessible from other threads, we need to acquire a lock before processing them
	 */
	public void incrementBallAfterRun() {
		
		// since we're updating RUN_COUNTER variable first, lock the Run.class reference first
		synchronized (Run.class) {
			
			// now acquire lock on Ball.class variable before updating BALL_COUNTER variable
			synchronized (Ball.class) {
				Run.RUN_COUNTER++;
				Ball.BALL_COUNTER++;
			}
		}
	}

	/**
	 * This method user to get increments BALL_COUNTER variable first and then increments the RUN_COUNTER  variable 
	 * since these variables are accessible from other threads, we need to acquire a lock before processing them
	 */
	public void incrementRunAfterBall() {

		// since we're updating BALL_COUNTER variable first, lock the Ball.class  reference first
		synchronized (Ball.class) {
			// now acquire lock on Run.class variable before updating RUN_COUNTER variable
			synchronized (Run.class) {
				Ball.BALL_COUNTER++;
				Run.RUN_COUNTER++;
			}
		}
	}

}

Output of sample

As you know execution orders are non-deterministic so its not guaranteed in same order always. That is why different out could be produced.

Output of sample code with deadlock

Waiting... for threads to complete execution.

Output of sample code without deadlock

Waiting... for threads to complete execution.
successfully executed , no deadlock situation.

References


Connect with

3 thoughts on “Theads Deadlock Example in Java

  1. Pingback: sumit

Leave a Reply

Your email address will not be published. Required fields are marked *