通过java自带的工具和linux命令来分析死锁

  当我们编写java程序时,由于不合理的设计,可能会出现程序死循环/死锁问题。

下面我就以程序的死锁为例,来进行分析

我编写的测试类是Run类

1.查找Run类对应的PID,使用命令:ps -ef | grep Run

lupeng    6765  4121  0 13:52 ?        00:00:00 /opt/java/jdk1.8.0_101/bin/java -Dfile.encoding=UTF-8 -classpath /home/lupeng/java_development/MultiThread/bin Run
lupeng    6795  2766  0 13:53 pts/0    00:00:00 grep --color=auto Run


2.利用java自带的工具jstack进行分析

jstack 6765

结果如下

Java stack information for the threads listed above:
===================================================
"Thread-1":
	at DeadThread.run(DeadThread.java:37)
	- waiting to lock <0x00000000ec1df068> (a java.lang.Object)
	- locked <0x00000000ec1df078> (a java.lang.Object)
	at java.lang.Thread.run(Thread.java:745)
"Thread-0":
	at DeadThread.run(DeadThread.java:21)
	- waiting to lock <0x00000000ec1df078> (a java.lang.Object)
	- locked <0x00000000ec1df068> (a java.lang.Object)
	at java.lang.Thread.run(Thread.java:745)

Found 1 deadlock.

deadlock说明出现死锁问题。

Thread-1 已经获得了锁<0x00000000ec1df078>,同时等待锁<0x00000000ec1df078>

Thread-0已经获得了锁<0x00000000ec1df078>,同时等待锁<0x00000000ec1df078>

一次发生了死锁问题。

Found one Java-level deadlock:
=============================
"Thread-1":
  waiting to lock monitor 0x00007fefcc003828 (object 0x00000000ec1df068, a java.lang.Object),
  which is held by "Thread-0"
"Thread-0":
  waiting to lock monitor 0x00007fefcc006218 (object 0x00000000ec1df078, a java.lang.Object),
  which is held by "Thread-1"

那么到底时什么地方出现了死锁问题呢?

我们再来分析下

Java stack information for the threads listed above:
===================================================
"Thread-1":
	at DeadThread.run(DeadThread.java:37)
	- waiting to lock <0x00000000ec1df068> (a java.lang.Object)
	- locked <0x00000000ec1df078> (a java.lang.Object)
	at java.lang.Thread.run(Thread.java:745)
"Thread-0":
	at DeadThread.run(DeadThread.java:21)
	- waiting to lock <0x00000000ec1df078> (a java.lang.Object)
	- locked <0x00000000ec1df068> (a java.lang.Object)
	at java.lang.Thread.run(Thread.java:745)

Found 1 deadlock.

其中有一行是at DeadThread.run(DeadThread.java:37)

说明Thread-1实在DeadThread类的37行处发生死锁

其中at DeadThread.run(DeadThread.java:21)

说明Thread-0实在DeadThread类的21行处发生死锁
接下来我们定位到具体代码:

public class DeadThread implements Runnable{
	public String username;
	public Object lock1 = new Object();
	public Object lock2 = new Object();
	
	@Override
	public void run() {
		// TODO Auto-generated method stub
		if(username.equals("a")){
			synchronized (lock1) {
				try {
					System.out.println("username = "+username);
					System.out.println(Thread.currentThread().getName());
					Thread.sleep(3000);
				} catch (Exception e) {
					// TODO: handle exception
					e.printStackTrace();
				}
				synchronized (lock2) {
					System.out.println("按lock1->lock2的顺序执行代码");
				}
			}
		}
		if(username.equals("b")){
			synchronized (lock2) {
				try{
						System.out.println("username = "+username);
						System.out.println(Thread.currentThread().getName());
						Thread.sleep(3000);
					
				}catch (Exception e) {
					// TODO: handle exception
					e.printStackTrace();
				}
				synchronized (lock1) {
					System.out.println("按lock2->lock1顺序执行代码");
				}
			}
			
		}
	}
	
	public void setFlag(String username){
		this.username=username;
	}
}


从而定位到死锁发生的原因,及具体位置:

Thread-0获得了锁lock1,接下来期望获得锁lock2,(20)

但是此时Thread-1获得了锁lock2,接下来期望获得锁lock2,(37)

因而发生了死锁。


    原文作者:java锁
    原文地址: https://blog.csdn.net/lu__peng/article/details/52822632
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞