Java 多线程中的死锁
java programming java8object oriented programming
死锁描述了两个或多个线程被永远阻塞,相互等待的情况。当多个线程需要相同的锁但以不同的顺序获取它们时,就会发生死锁。Java 多线程程序可能会遭遇死锁情况,因为 synchronized 关键字会导致执行线程在等待与指定对象关联的锁或监视器时阻塞。下面是一个例子。
示例
public class TestThread { public static Object Lock1 = new Object(); public static Object Lock2 = new Object(); public static void main(String args[]) { ThreadDemo1 T1 = new ThreadDemo1(); ThreadDemo2 T2 = new ThreadDemo2(); T1.start(); T2.start(); } private static class ThreadDemo1 extends Thread { public void run() { synchronized (Lock1) { System.out.println("Thread 1: Holding lock 1..."); try { Thread.sleep(10); } catch (InterruptedException e) {} System.out.println("Thread 1: Waiting for lock 2..."); synchronized (Lock2) { System.out.println("Thread 1: Holding lock 1 & 2..."); } } } } private static class ThreadDemo2 extends Thread { public void run() { synchronized (Lock2) { System.out.println("Thread 2: Holding lock 2..."); try { Thread.sleep(10); } catch (InterruptedException e) {} System.out.println("Thread 2: Waiting for lock 1..."); synchronized (Lock1) { System.out.println("Thread 2: Holding lock 1 & 2..."); } } } } }
当你编译并执行上述程序时,你会发现一个死锁的情况,以下是程序产生的输出 −
输出
Thread 1: Holding lock 1... Thread 2: Holding lock 2... Thread 1: Waiting for lock 2... Thread 2: Waiting for lock 1...
上述程序将永远挂起,因为两个线程都无法继续执行,并且都在等待对方释放锁,因此您可以按 CTRL+C 退出程序。
死锁解决方案示例
让我们改变同一程序的锁定和运行顺序,看看两个线程是否仍在等待对方 −
示例
public class TestThread { public static Object Lock1 = new Object(); public static Object Lock2 = new Object(); public static void main(String args[]) { ThreadDemo1 T1 = new ThreadDemo1(); ThreadDemo2 T2 = new ThreadDemo2(); T1.start(); T2.start(); } private static class ThreadDemo1 extends Thread { public void run() { synchronized (Lock1) { System.out.println("Thread 1: Holding lock 1..."); try { Thread.sleep(10); } catch (InterruptedException e) {} System.out.println("Thread 1: Waiting for lock 2..."); synchronized (Lock2) { System.out.println("Thread 1: Holding lock 1 & 2..."); } } } } private static class ThreadDemo2 extends Thread { public void run() { synchronized (Lock1) { System.out.println("Thread 2: Holding lock 1..."); try { Thread.sleep(10); } catch (InterruptedException e) {} System.out.println("Thread 2: Waiting for lock 2..."); synchronized (Lock2) { System.out.println("Thread 2: Holding lock 1 & 2..."); } } } } }
因此,只需改变锁的顺序即可防止程序陷入死锁情况,并完成以下结果 −
输出
Thread 1: Holding lock 1... Thread 1: Waiting for lock 2... Thread 1: Holding lock 1 & 2... Thread 2: Holding lock 1... Thread 2: Waiting for lock 2... Thread 2: Holding lock 1 & 2...