`
youyu4
  • 浏览: 425447 次
社区版块
存档分类
最新评论

Java多线程之死锁

 
阅读更多

Java多线程之死锁

 

什么是死锁

 

      A、B两台车过桥,桥只能过一台车,A、B分别是桥的两头,A不让B,B不让A

 

 

 

怎么查出死锁(两种方法)

 

方法一

  • JConsole找到本地进程
  • 找到线程选项卡,然后检查死锁
  • 找到blocked状态的线程,看它需要资源的拥有者

方法二

  • JVM自带的命令jps查看进程
  • Jstack查看栈的使用情况

 

 

怎样从死锁中恢复过来

 

     1. 重启系统,代价大,之前的工作白费,所有正在运行的现场都去掉了

 

     2. 撤销进程,剥夺资源。终止参与死锁的进程,回收他们占的资源,从而解除死锁。这又分两种,一次性撤销参与死锁的全部进程,剥夺全部资源;或者逐步撤销参与死锁的进程。一般来说,逐步撤销要按一定的原则,目的是撤销代价最小的进程,比如按优先级确定线程代价。

 

     3. 进程回退,死锁的线程回退到没有发生死锁的某一点,继续执行。

 

 

 

死锁条件

 

  • 互斥:资源在一段时间内只能被一个线程使用
  • 不可抢占:不能强行从别的线程将资源抢走
  • 占有且申请:自己占有资源,又申请另一个资源
  • 循环

 

 

避免死锁的方法

 

  • 打破上面的条件,就能解除或避免死锁
  • 避免嵌套锁,只有需要的地方使用锁
  • 避免无限期等待也是避免死锁的常用方法
  • 使用一些避免死锁的算法:有序资源分配法、银行家算法

 

 

N个线程访问N个资源,同时不死锁,用下面算法解决

 

有序资源排序法

 

线程所需要的资源统一编号,申请资源时一定要按照编号顺序申请。

例子

  1. 线程A使用资源的顺序时R1、R2,线程B使用资源的顺序是R2、R1,这样就可能导致死锁
  2. 有序资源分配法:R1编号为1,R2编号为2
  3. A申请资源的顺序是R1、R2,B申请资源的顺序是R1、R2,就不会出现死锁了

 

银行家算法

 

  1. 当线程首次申请资源时,要测试改线程对资源的最大需求量,如果资源能满足最大请求量,就分配,否则推迟分配
  2. 当线程在执行中继续申请资源,先测试该线程本次申请的资源数是否超过了该资源所剩余的总量,如满足则分配,不满足则推迟

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics