上QQ阅读APP看书,第一时间看更新
2.2.19 多线程的死锁
Java线程死锁是一个经典的多线程问题,因为不同的线程都在等待根本不可能被释放的锁,导致所有的任务都无法继续完成。在多线程技术中,“死锁”是必须要避免的,因为这会造成线程的“假死”。
创建名称为deadLockTest的项目,DealThread.java类代码如下:
package test; public class DealThread implements Runnable { public String username; public Object lock1 = new Object(); public Object lock2 = new Object(); public void setFlag(String username) { this.username = username; } @Override public void run() { if (username.equals("a")) { synchronized (lock1) { try { System.out.println("username = " + username); Thread.sleep(3000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } synchronized (lock2) { System.out.println("按lock1->lock2代码顺序执行了"); } } } if (username.equals("b")) { synchronized (lock2) { try { System.out.println("username = " + username); Thread.sleep(3000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } synchronized (lock1) { System.out.println("按lock2->lock1代码顺序执行了"); } } } } }
运行类Run.java代码如下:
package test; public class Run { public static void main(String[] args) { try { DealThread t1 = new DealThread(); t1.setFlag("a"); Thread thread1 = new Thread(t1); thread1.start(); Thread.sleep(100); t1.setFlag("b"); Thread thread2 = new Thread(t1); thread2.start(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
程序运行结果如图2-56所示。
图2-56 死锁了
可以使用JDK自带的工具来监测是否有死锁现象,首先进入CMD工具,再进入JDK的安装文件夹中的bin目录,执行jps命令,如图2-57所示。
图2-57 执行jps命令
得到运行线程Run的id值是3244,再执行jstack命令,查看结果,如图2-58所示。
图2-58 执行jstack命令
监测出有死锁现象,如图2-59所示。
图2-59 出现死锁
死锁是程序设计的Bug,在设计程序时就要避免双方互相持有对方的锁,只要互相等待对方释放锁,就有可能出现死锁。