以前咱们简单的讨论了一下关于Java
中的同步还有一些锁优化的问题,今天咱们就来简单的聊一聊关于Java
中的死锁
问题。多线程
这个问题咱们在开发的时候,或多或少都能遇到,对业务逻辑没有正确的梳理,又或者是在多线程的状况下,对程序的执行顺序有理解上的误差等等,可是这种问题有时候执行代码是看不出来的,那咱们今天就看一看如何使用简单的命令来查看死锁。ide
首先咱们得写一段有问题的程序,固然前提条件是先要明确什么是死锁,这个问题在网上找有不少的资料,在这里咱们就不重复叙述了,先来看一下代码工具
class Lock extends Thread{ private String lock1; private String lock2; Lock(String s1, String s2){ this.lock1 = s1; this.lock2 = s2; } @Override public void run() { synchronized (lock1) { System.out.println(Thread.currentThread().getName() + " get " + lock1); try { Thread.sleep(1 * 1000); synchronized (lock2) { System.out.println(Thread.currentThread().getName() + " get -- " + lock2); } } catch (InterruptedException e) { e.printStackTrace(); } } } } public static void main(String[] args) throws InterruptedException { Thread thread1 = new Thread(new Lock(LOCK_1, LOCK_2)); Thread thread2 = new Thread(new Lock(LOCK_2, LOCK_1)); thread1.start(); thread2.start(); thread1.join(); thread2.join(); }
在这里咱们用synchronized
来嵌套两层,而后赋予两个线程两个交互的锁,那么这段代码在大部分状况下会发生死锁,可是咱们的程序执行下来没有报错,那这个该如何查看呢?JDK
为咱们提供了一些工具,咱们来看一下,首先用jps
这个命令查看当前的PID
,这个就和ps
命令差很少。优化
而后咱们再用jstack
来查看具体的栈信息,例如:jstack 9520
,会打印不少的信息,咱们看几个比较重要的。this
这里显示两个线程的状态如今是处于阻塞状态,而后都在等待锁的获取,咱们再继续往下看。
这里很明确的指出线程3在等待一个锁获取,可是这个锁被线程1持有,反过来也是同样,线程1也在等待一个锁获取,可是这个锁又被线程3持有,那么这里就产生了一个死锁。spa
JDK
的这些命令行工具能很好的帮助咱们分析程序中的一些问题,可是咱们在平常的开发工做中,该如何规避这些问题呢,其实个人建议只有一点,首先要明确理论,有了必定的理论作基础,而后就是不断的实践采坑,这样才能明白某些问题的点在哪里。命令行