线程死锁及如何使用JDK自带工具监测是否有死锁现象

来源:互联网 发布:掃描sql 编辑:程序博客网 时间:2024/05/19 06:51

Java线程死锁原因:不同线程都在等待根本不可能被释放的锁,从而导致所有的任务都无法继续完成。举个栗子:两个线程互相等待对方释放锁。

/** * Created by LZF on 2017/7/14. * 学习:如何查看多线程死锁   */class DealThread implements Runnable{    public String username;    public Object lock1 = new Object();    public Object lock2 = new Object();    public void setFlag(String username){        this.username = username;    }    @Override    public void run(){        if(username.equals("a")){            synchronized (lock1){                try{                    System.out.println("username = " + username);                    Thread.sleep(3000);                }catch(InterruptedException e){                    e.printStackTrace();                }                synchronized (lock2){                    System.out.println("按lock1->lock2代码顺序执行了");                }            }        }        if(username.equals("b")){            synchronized (lock2){                try{                    System.out.println("username = " + username);                    Thread.sleep(3000);                }catch(InterruptedException e){                    e.printStackTrace();                }                synchronized (lock1){                    System.out.println("按lock2->lock1代码顺序执行了");                }            }        }    }}public class Run_13 {    public static void main(String[] args){        try{            DealThread t1 = new DealThread();            t1.setFlag("a");            Thread thread1 = new Thread(t1);            thread1.start();            Thread.sleep(100);            t1.setFlag("b");            Thread thread2 = new Thread(t1);            thread2.start();        }catch(InterruptedException e){            e.printStackTrace();        }    }}

结果:出现死锁,无法继续执行
这里写图片描述


在使用JDK自带的工具监测是否有死锁的现象前,先介绍两个命令:
- jps(Java Virtual Machine Process Status Tool)是JDK 1.5提供的一个显示当前所有Java进程pid的命令,简单实用,非常适合在Linux/unix平台上简单察看当前java进程的一些简单情况。
- jstack是java虚拟机自带的一种堆栈跟踪工具。jstack用于生成java虚拟机当前时刻的线程快照。线程快照是当前java虚拟机内每一条线程正在执行的方法堆栈的集合,生成线程快照的主要目的是定位线程出现长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致的长时间等待等。

线程出现停顿的时候通过jstack来查看各个线程的调用堆栈,就可以知道没有响应的线程到底在后台做什么事情,或者等待什么资源。
命令格式:jstack [ option ] pid
[options]选项 :
-F :当’jstack [-l] pid’没有响应的时候强制打印栈信息;
-l :长列表. 打印关于锁的附加信息,例如属于java.util.concurrent的ownable synchronizers列表.
-m: 打印java和native c/c++框架的所有栈信息. -h | -help打印帮助信息
pid :需要被打印配置信息的java进程id,可以用jps工具查询


可以使用JDK自带的工具监测是否有死锁的现象。进入CMD -> 打开JDK的安装文件夹中的bin目录 -> 执行jsp命令 如下图所示:
这里写图片描述
得到运行的线程Run的id值是13088,再执行jstack命令,监测出有死锁现象,如下图所示:
这里写图片描述

只要互相等待对方释放锁就有可能出现死锁。

参考书籍:《Java多线程编程核心技术》–高洪岩