zoukankan      html  css  js  c++  java
  • 使用JDK自带的工具jstack找出造成运行程序死锁的原因

    Java多线程编程也是Java面试中经常考察的内容。刚接触Java多线程编程的朋友们,可能会不慎写出一些会导致死锁(deadlock)的应用出来。如何分析造成Java多线程的原因呢?很多时候我们在怀疑造成死锁的语句设置断点,单步调试,反而又不能重现了。这种现象很正常,因为咱们单步调试和直接运行程序,代码执行的时序是不同的,很可能无法满足死锁的触发条件。

    实际上,JDK已经给Java程序员提供了强大的死锁分析工具,能够直接分析一个正在运行的并且处于死锁状态的应用,并给出具体是哪一行Java代码引起的死锁。

    这篇文章就以一个例子来给大家演示如何使用这个JDK提供的标准工具。

    这个工具叫jstack,就是JDK安装目录的bin文件夹下的一个执行文件。

    我们首先写一个会导致死锁的应用出来。

    public class DeadLockExample {
    	public static void main(String[] args) {
    		final String resource1 = "ABAP";
    		final String resource2 = "Java";
    		Thread t1 = new Thread() {
    			public void run() {
    				synchronized (resource1) {
    					System.out.println("Thread 1: locked resource 1");
    					try {
    						Thread.sleep(100);
    					}
    					catch (Exception e) {
    					}
    					synchronized (resource2) {
    						System.out.println("Thread 1: locked resource 2");
    					}
    				}
    			}
    		}
    		;
    		Thread t2 = new Thread() {
    			public void run() {
    				synchronized (resource2) {
    					System.out.println("Thread 2: locked resource 2");
    					try {
    						Thread.sleep(100);
    					}
    					catch (Exception e) {
    					}
    					synchronized (resource1) {
    						System.out.println("Thread 2: locked resource 1");
    					}
    				}
    			}
    		}
    		;
    		t1.start();
    		t2.start();
    	}
    }
    

    这个应用思路很简单,同时启动两个线程,分别锁住了resource1和resource2,然后休眠0.1秒,接着分别尝试去请求资源resource2和resource1。

    执行应用,在控制台打印出下列输出后,进入死锁状态:

    Thread 1: locked resource 1

    Thread 2: locked resource 2

    使用命令行 jps -l -m找到处于死锁状态应用的进程id。从下图得知死锁进程为51476:

    然后使用命令行jstack 51476打印这个进程的运行栈信息。

    我上图红色高亮出的 0x00000000d6f64988 和 0x00000000d6f649b8代表了代码中的两个资源“ABAP” 和“Java”。

    jstack打印的输出非常清晰,显示了具体哪行Java代码试图去锁定哪一个Java资源(下图的waiting to lock)但是没有成功, 并且将失败的原因,即拥有当前请求资源的线程名称也打印了出来。

    有了jstack,Java程序员不用对着冗长烧脑的多线程代码去冥思苦想了,JDK会自动把死锁原因打印出来,太方便了。

    要获取更多Jerry的原创技术文章,请关注公众号"汪子熙"或者扫描下面二维码:

  • 相关阅读:
    Chrome cookies folder
    Fat URLs Client Identification
    User Login Client Identification
    Client IP Address Client Identification
    HTTP Headers Client Identification
    The Personal Touch Client Identification 个性化接触 客户识别
    购物车 cookie session
    购物车删除商品,总价变化 innerHTML = ''并没有删除节点,内容仍存在
    453
    购物车-删除单行商品-HTMLTableElement.deleteRow()
  • 原文地址:https://www.cnblogs.com/sap-jerry/p/9818882.html
Copyright © 2011-2022 走看看