一:死锁的定义:

  1. 多个进程争抢同一个资源,从而进入相互等待的循环状态,以至于没有一个线程可以继续运行。

1.产生死锁的四个条件:

  1. 互斥条件:任务使用的资源中只要有一个是不能共享的
  2. 至少有一个任务它必须持有一个资源且正在等待获取一个当前被别的任务持有的资源
  3. 资源不能被任务抢占。只能等待任务自己释放资源
  4. 必须要有循环等待。一个任务在等待另一个任务所持有的资源,后者又在等待另一个任务所持有的资源。这样一直到有一个任务在等待第一个任务所持有的资源。

2.死锁示列:

  1. class Block_One{
  2. Block_Two block_two;
  3. public void setBlock_two(Block_Two block_two) {
  4. this.block_two = block_two;
  5. }
  6. public synchronized void f(){
  7. System.out.println(Thread.currentThread().getName()+" f() ------- Block_One");
  8. block_two.test();
  9. }
  10. public synchronized void g(){
  11. System.out.println(Thread.currentThread().getName()+" g() ------- Block_One");
  12. }
  13. }
  14. class Block_Two{
  15. Block_One block_One;
  16. public void setBlock_One(Block_One block_One) {
  17. this.block_One = block_One;
  18. }
  19. public synchronized void info(){
  20. System.out.println(Thread.currentThread().getName()+" info ====== Block_Tow");
  21. block_One.g();
  22. }
  23. public synchronized void test(){
  24. System.out.println(Thread.currentThread().getName()+" test ======= Block_Tow");
  25. }
  26. }
  27. public class DeadLockDemo {
  28. public static void main(String[] args) {
  29. Block_Two block_two = new Block_Two();
  30. Block_One block_one = new Block_One();
  31. block_one.setBlock_two(block_two);
  32. block_two.setBlock_One(block_one);
  33. new Thread(()->{
  34. while (!Thread.interrupted()){
  35. block_one.f();
  36. }
  37. },"AA").start();
  38. new Thread(()->{
  39. while (!Thread.interrupted()){
  40. block_two.info();
  41. }
  42. },"BB").start();
  43. }
  44. }

示列详解

  1. 以上两个线程,线程AA在调用block_one.f();f方法时要进入到block_two中的test()方法中,线程BB调用blocKTow中的info()方法时要进入block_one中的g()方法。由于两个类中的方法都是加锁的。所以当线程AA进入block_two.test();时,线程BB也要进入 block_One.g();此时这两个方法的锁都没有被释放,所以两个线程都在等待释放锁,同时这两个线程还是在不断的循环等待,所以就造成了死锁。

3.死锁的解决方案:

只需要破话任务争抢的资源即可
示列:破坏死锁示列

  1. class Block_One{
  2. Block_Two block_two;
  3. public void setBlock_two(Block_Two block_two) {
  4. this.block_two = block_two;
  5. }
  6. public synchronized void f(){
  7. System.out.println(Thread.currentThread().getName()+" f() ------- Block_One");
  8. block_two.test();
  9. }
  10. public void g(){
  11. System.out.println(Thread.currentThread().getName()+" g() ------- Block_One");
  12. }
  13. }
  14. class Block_Two{
  15. Block_One block_One;
  16. public void setBlock_One(Block_One block_One) {
  17. this.block_One = block_One;
  18. }
  19. public synchronized void info(){
  20. System.out.println(Thread.currentThread().getName()+" info ====== Block_Tow");
  21. block_One.g();
  22. }
  23. public void test(){
  24. System.out.println(Thread.currentThread().getName()+" test ======= Block_Tow");
  25. }
  26. }
  27. public class DeadLockDemo {
  28. public static void main(String[] args) {
  29. final Block_Two block_two = new Block_Two();
  30. final Block_One block_one = new Block_One();
  31. block_one.setBlock_two(block_two);
  32. block_two.setBlock_One(block_one);
  33. new Thread(()->{
  34. while (!Thread.interrupted()){
  35. block_one.f();
  36. }
  37. },"AA").start();
  38. new Thread(()->{
  39. while (!Thread.interrupted()){
  40. block_two.info();
  41. }
  42. },"BB").start();
  43. }
  44. }

示列详解:

  1. 由于上个死锁的示列是在争抢同一把锁,所以只需要破话其中的一把锁就可以解决死锁了。

二、如何查看死锁:

1、Jps中的Jstack命令

  1. jstackjava虚拟机自带的一种堆栈跟踪工具。 <br /> 示列:查看死锁<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/12862216/1622031997581-cf8f4864-2737-4624-9d19-38221384d1ad.png#clientId=u5e20c3fa-d395-4&from=paste&id=ud1a94b78&margin=%5Bobject%20Object%5D&name=image.png&originHeight=179&originWidth=748&originalType=binary&size=14320&status=done&style=none&taskId=ua69c3025-b09e-49a9-8156-dd49b97c8d5)<br />![屏幕截图 2021-05-26 202705.jpg](https://cdn.nlark.com/yuque/0/2021/jpeg/12862216/1622032173783-5a028fbf-8993-4571-8933-fd359909d2b4.jpeg#clientId=u5e20c3fa-d395-4&from=ui&id=u6b7fcd4c&margin=%5Bobject%20Object%5D&name=%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202021-05-26%20202705.jpg&originHeight=763&originWidth=1326&originalType=binary&size=224384&status=done&style=none&taskId=u34dc11f5-75a5-40bf-90f1-c240d2a61ed)

2、Jconsole工具

Jconsole是JDK自带的监控工具,在cmd命令模式下输入即可打开
image.png

[

](https://blog.csdn.net/hd12370/article/details/82814348)