package com.example.sync;

// this example using synchronized block
public class DeadlockExample {

	private final Object lock1 = new Object();
	private final Object lock2 = new Object();

	public void method1() {
		System.out.println(Thread.currentThread().getName() + " calling method1 ...");
		synchronized (lock1) { // get lock1 - t1
			System.out.println("Thread 1: Holding lock 1...");
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
			}
			synchronized (lock2) { // try to get lock2 - currently hold by t2
				System.out.println("Thread 1: Holding lock 1 & 2...");
			}
		}
	}

	public void method2() {
		System.out.println(Thread.currentThread().getName() + " calling method2 ...");
		synchronized (lock2) { // get lock2 - t2
			System.out.println("Thread 2: Holding lock 2...");
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
			}
			synchronized (lock1) { // try to get lock1 - currently hold by t1
				System.out.println("Thread 2: Holding lock 2 & 1...");
			}
		}
	}

	public static void main(String[] args) {
		DeadlockExample example = new DeadlockExample();
		
		Thread t1 = new Thread(example::method1, "t1");
		Thread t2 = new Thread(example::method2, "t2");

		t1.start();
		t2.start();
	}

}
