线程死锁检测方法

原创 2015年08月12日 20:04:16

多条线程以不同的顺序抢占同步资源的时候,就有可能发生死锁。

如下图所示,线程1持有锁对象A而希望获得锁对象B;另一方面,线程2持有锁对象B而希望

获得锁对象A。并且这两个线程的操作是交错执行的,因此它们会发生死锁。


当发生的死锁后,JDK自带了两个工具(jstack和JConsole),可以用来监测分析死锁的发生原因。

jstack工具用于生于生成虚拟机当前时刻的线程快照。线程快照就是当前虚拟机每一条线程正在

执行的方法堆栈的集合,生成快照可以用于定位诸如线程死锁、死循环等问题。

JConsole是一种可视化监视管理工具。用于连接正在运行的JVM进程,以监控 Java 应用程序性

能和跟踪 Java 中的代码。

下面以一个死锁例子来说明如何使用这两个工具来分析线程死锁。

死锁示例代码如下:

class SynThread implements Runnable{
	
	int a ,b;
	
	public SynThread(int a,int b){
		this.a=a;
		this.b=b;
	}
	@Override
	public void run() {
		synchronized (Integer.valueOf(a)) {//必须用valueOf()方法
			synchronized (Integer.valueOf(b)) {
				System.err.println("a+b=="+(a+b));
			}
		}
	}
	
}

public class entry {

	public static void main(String[] args) {
		
		//循环主要是为了加大死锁概率
		for(int i=0;i<100;i++){
			new Thread(new SynThread(1,2)).start();
			new Thread(new SynThread(2,1)).start();
		}
	}
}

说明:以上代码有可能发生死锁,原因是Integer.valueOf()方法作了缓存优化,对[-128,127]之间

的数字会被缓存。也就是说,循环代码中一共只创建了两个不同的对象。假设在两个synchronized

块之间发生了线程切换,那就有可能造成,线程A等待被线程B持有Integer.valueOf(1)对象,线程B

等待被线程A持有Integer.valueOf(2)对象,结果出现了死锁。(可能需要多次执行直到程序出现

阻塞现象)


JDK源代码Integer.java类对valueOf()方法的优化细节如下

    public static Integer valueOf(int i) {
        if(i >= -128 && i <= IntegerCache.high)
            return IntegerCache.cache[i + 128];
        else
            return new Integer(i);
    }

  • 使用jstack工具导出线程堆栈信息(以Windows环境为例)

1.找到运行当前程序的JVM的进程id,命令及结果如下



2.运行jstack命令,并将结果信息导出来


3.使用文本编辑器打开刚导出的文本,只要查看最后关于死锁的堆栈信息即可


4.直接从堆栈信息不能直观得到结论,没关系,我们可以画图理清线程间的调度情况

出现闭合环路,发生死锁


  • 使用JConsole可视化工具检测死锁

1.直接执行JConsole工具(在jdk/bin目录下),选择目标JVM进程,然后点击连接


2.切换到“线程”标签页,点击“检测死锁”按钮



3.选择不同的线程,可以查看其资源调度信息,采用类似的方法分析,可以得出与

采用jstack分析一样的结论




版权声明:本文为博主原创文章,未经博主允许不得转载。

死锁怎么检测?

先OO分析、建模,再研究具体问题。这里面涉及的对象: 1)线程 2)锁 关系: 占有:线程——锁 的一对多关系:一个线程可以占有多个锁,一个锁只能被一个线程占有 等待:线程——锁 的多对多关系:一个线...
  • binling
  • binling
  • 2015年10月09日 15:51
  • 1501

Delphi7高级应用开发随书源码

  • 2003年04月30日 00:00
  • 676KB
  • 下载

linux死锁检测的一种思路

linux死锁检测的一种思路 http://www.cnblogs.com/mumuxinfei/p/4365697.html 前言:    上一篇博文讲述了pstack的使用和原理...

进程死锁(银行家算法)

1、死锁:在计算机系统中有许多互斥资源(如打印机)或软件资源(如临界区),若两个进程同时使用打印机,或者同时进入临界区必然会出现问题。所谓死锁,是指两个以上的进程互相都要求对方已经占有的资源导致无法继...
  • jyhye
  • jyhye
  • 2012年10月03日 21:15
  • 6570

死锁的检测和解除

死锁的检测和解除

操作系统面试—死锁(三)——死锁检测和死锁恢复

本文是对操作系统概念(第七版)——死锁的学习总结,不足之处,欢迎批评指正。 本文讨论的两块内容是死锁检测和死锁恢复。 1、死锁检测 首先针对每种资源类型只有一个实例的情况。 该算法使用资源分配图的一个...

死锁的产生以及避免原理和算法

死锁 是指多个并发进程在运行过程中因竞争资源而造成的一种僵局,当进程处于这种僵持状态时,若无外力作用,这些进程都无法向前推进。并发性 : 指两个或多个事件在同一时刻发生 并行性 : 指两个或多个事件在...
  • JenaeLi
  • JenaeLi
  • 2017年06月08日 14:14
  • 438

构成死锁的必要条件是什么?如何检测死锁,解除死锁?

产生死锁的原因主要是: (1) 因为系统资源不足。 (2) 进程运行推进的顺序不合适。 (3) 资源分配不当等。 如果系统资源充足,进程的资源请求都能够得到满足,死锁出现的可能性就很低,否则 ...

什么是死锁以及死锁的预防、检测与修复

来自http://blog.163.com/yanenshun@126/blog/static/128388169200982444858590/?fromdm&fromSearch&isFromSe...

Intellij idea快速查看Java类字节码

原文地址,点击打开链接 最近在研究JVM类加载、JVM字节码相关的东西,需要经常查看字节码。之前都是用一些外部工具例如bytecoder、JD或者直接cmd使用javap的方式查看字...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:线程死锁检测方法
举报原因:
原因补充:

(最多只允许输入30个字)