java多线程(5)死锁

发布时间:2019-11-19 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了java多线程(5)死锁脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。

上文讲到synchronized关键字在多线程中的使用,既然用到了锁,就会有出现死锁的情况。一个线程获得锁,如果其他线程也想获得同样的锁就会阻塞住,等待锁的释放。如果线程A已经获得锁1,还要获得锁2,同时线程B已经获得锁2,还要获得锁1,那么线程A和B就会一直阻塞住。

例子

依照惯例先举个例子:

 public class test {                public static void main(String[] args) throws InterruptedException {         Object lock1 = new Object();         Object lock2 = new Object();         Thread t1 = new Thread(new Test().new Tt1(lock1, lock2));         Thread t2 = new Thread(new Test().new Tt2(lock1, lock2));         t1.start();         t2.start();     }               class Tt1 implements Runnable{          PRivate Object lock1;         private Object lock2;                  public Tt1(Object lock1,Object lock2) {             this.lock1 = lock1;             this.lock2 = lock2;         }          @override         public void run() {                          synchronized (lock1) {                 System.out.println(this.getClass()+"-------1");                 try {                     Thread.sleep(1000);                     synchronized (lock2) {                         System.out.println(this.getClass()+"-------2");                     }                 } catch (InterruptedException e) {                     e.printStackTrace();                 }             }         }     }          class Tt2 implements Runnable{          private Object lock1;         private Object lock2;                  public Tt2(Object lock1,Object lock2) {             this.lock1 = lock1;             this.lock2 = lock2;         }          @Override         public void run() {                          synchronized (lock2) {                 System.out.println(this.getClass()+"-------1");                 try {                     Thread.sleep(1000);                     synchronized (lock1) {                         System.out.println(this.getClass()+"-------2");                     }                 } catch (InterruptedException e) {                     e.printStackTrace();                 }             }         }     } } 

执行结果:

class Test$Tt1-------1 class Test$Tt2-------1 

2个线程都只执行到了第一步,就没有往下执行,都处于了阻塞状态,这就是死锁。

定位死锁

死锁问题并不是一个容易被发现和定位的问题,如果系统出现死锁问题,该如何定位?

1.使用jps,查询java虚拟机的pid

java多线程(5)死锁


2.使用jstack打印堆栈

java多线程(5)死锁

以Thread-1为例介绍下每一部分的意思
1).Thread-1 线程名称
2).prio=5 线程优先级
3).os_prio=0 本地的优先级
4).tid=0x000000001929b800 线程id
5).nid=0xfb34 本地的线程id
6)
java.lang.Thread.State: BLOCKED (on object monITor)
线程状态处于阻塞
7) waiting to lock <0x00000000d5dd0c38> (a java.lang.Object)正在等待的锁
8)locked <0x00000000d5dd0c48> (a java.lang.Object) 已获取的锁

现在我们可以看到Thread-1和Thread-0都处于阻塞状态,Thread-1获取了‘0x00000000d5dd0c48’锁,等待‘0x00000000d5dd0c38’锁,而Thread-0则刚好相反。

避免死锁

我们已经知道了死锁的形成和定位,再来讲讲如何避免:
1.尽量在线程中不嵌套获取多个资,但你只需获取一个时就不会出现死锁、
2.如果不得不嵌套使用时,要多考虑嵌套的顺序
3.死锁是因为无限的阻塞等待,如果能有一个最大的等待时间就可以解决这个问题。synchronized不具备这个功能,但是我们可以使用Lock类中的tryLock方法去尝试获取锁,这个方法可以指定一个超时时限,在等待超过该时限之后返回失败信息

脚本宝典总结

以上是脚本宝典为你收集整理的java多线程(5)死锁全部内容,希望文章能够帮你解决java多线程(5)死锁所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。