Java Deadlock Example

Deadlock is a reason which causes the java program to hang. The reason for this may be two or more java threads are waiting for each other to release the locked objects which they want to lock also. Of course, we should avoid this kind of situation in java programming. This article will show you java deadlock examples and how to avoid them.

1. Java Deadlock Example Code.

  1. There are three classes in our example code.
  2. Car: This class represents a Car. It has one field with the name brand.
  3. CarBuyer: This class has three fields, buyerName, firstCar, and secondCar.
  4. One CarBuyer can first lock firstCar for a look. After some time he will acquire to lock the secondCar.
  5. If the acquire success, it will look it for some time also, if fail the program will hang.
  6. MultiThreadDeadLock: This is the test class that will create two Car objects, and use them to create two CarBuyer objects. Then start the two CarBuyer thread object one by one.
  7. Now the deadlock happened, because carBuyer1 locked firstCar and acquire to lock secondCar, will fail because at the same time carBuyer2 locked secondCar and acquire to lock firstCar will also fail.
    public class MultiThreadDeadLock {
    
    	public static void main(String[] args) throws InterruptedException {
    		
    		Car c1 = new Car("Ford");
    		Car c2 = new Car("Audi");
    		
    		CarBuyer cb1 = new CarBuyer("Tom", c1, c2);
    		cb1.start();
    		
    		Thread.sleep(1000);
    		
    		CarBuyer cb2 = new CarBuyer("Richard", c2, c1);
    		cb2.start();
    
    	}
    
    }
    
    /* This is the thread object which will acquire two cars one by one.*/
    class CarBuyer extends Thread{
    	
    	private String buyerName; 
    	private Car firstCar;
    	private Car secondCar;	
    
    	public CarBuyer(String bName, Car c1, Car c2) {
    		this.buyerName = bName;
    		this.firstCar = c1;
    		this.secondCar = c2;
    	}
    
    	
    	
    	@Override
    	public void run() {
    	
    		System.out.println(this.buyerName + " require lock on " + this.firstCar.getBrand());
    		synchronized(this.firstCar)
    		{
    			System.out.println(this.buyerName + " locked on "+ this.firstCar.getBrand());
    			this.threadSleep();
    			
    			System.out.println(this.buyerName + " require lock on " + this.secondCar.getBrand());
    			synchronized(this.secondCar)
    			{
    				System.out.println(this.buyerName + " locked on "+ this.secondCar.getBrand());
    				this.threadSleep();
    			}
    			
    			System.out.println(this.buyerName + " release on "+ this.secondCar.getBrand());
    		}
    		
    		System.out.println(this.buyerName + " release on "+ this.firstCar.getBrand());
    		
    		System.out.println(this.buyerName + " finish choose.");
    	}
    	
    	
    	private void threadSleep() {
            try {
                Thread.sleep(10000);
            } catch (InterruptedException ex) {
                ex.printStackTrace();
            }
        }
    }
    
    
    /* This class represent a car. */
    class Car{
    	
    	private String brand = "";
    
    	public Car(String brand) {
    		this.brand = brand;
    	}
    
    	public String getBrand() {
    		return brand;
    	}
    
    	public void setBrand(String brand) {
    		this.brand = brand;
    	}
    }
  8. Below is the above example output.
    Tom require lock on car Ford
    Tom locked on car Ford
    Richard require lock on car Audi
    Richard locked on car Audi
    Tom require lock on car Audi
    Richard require lock on car Ford

2. How To Prevent Deadlock In Java.

  1. Avoid Nested Object Locks: Do not lock objects inside other lock code blocks. This can avoid deadlock easily. If we change the example code as below, the deadlock will disappear.
    	@Override
    	public void run() {
    	
    		System.out.println(this.buyerName + " require lock on " + this.firstCar.getBrand());
    		synchronized(this.firstCar)
    		{
    			System.out.println(this.buyerName + " locked on "+ this.firstCar.getBrand());
    			this.threadSleep();
    		}
    		
    		System.out.println(this.buyerName + " release on "+ this.firstCar.getBrand());
    		
    		System.out.println(this.buyerName + " require lock on " + this.secondCar.getBrand());
    		synchronized(this.secondCar)
    		{
    			System.out.println(this.buyerName + " locked on "+ this.secondCar.getBrand());
    			this.threadSleep();
    		}
    		
    		System.out.println(this.buyerName + " release on "+ this.secondCar.getBrand());
    		
    		System.out.println(this.buyerName + " finish choose.");
    	}
  2. Set Timeout For Waiting: If you use the java thread join() method to let another thread object wait for execution. You had better use join(long timeout). This version of the join() method will not let other thread objects wait forever. If the first thread object hangs, it will not cause deadlock because the second thread object will just wait for the timeout milliseconds.
  3. Lock Just You Need: If you just want to lock particular fields of one java object, please do not synchronize the object entirely. Just lock what you need.

Leave a Comment

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.