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

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

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

我编写的测试类是Run类

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

 

gl    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
gl    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)

因而发生了死锁。
 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
JavaLinux都是非常常用的软件开发工具。但是,无论是Java还是Linux都存在可能导致的情况。 在Java中,是指两个或多个线程相互等待对方持有的资源,而导致所有线程都无法继续执行的情况。这通常发生在多线程编程中,当多个线程尝试以不同的顺序定多个资源时,可能会导致。例如,线程A持有资源X并等待获取资源Y,而线程B持有资源Y并等待获取资源X,这样就会导致。 在Linux中,是指多个进程或线程由于争夺有限的系统资源而无限期地相互等待对方释放资源的情况。这种情况通常发生在系统资源(如内存、文件描述符等)不足时,多个进程或线程同时请求这些资源,但由于资源分配不当而无法满足所有请求,从而导致。 对于Java中的,可以通过使用的合理顺序、避免使用多个或使用的超时机制来预防。另外,通过使用工具如检测工具(如jstack)可以帮助发现和解决问题。 对于Linux中的,可以通过合理规划和分配系统资源、采用进程/线程优先级策略、使用资源分配算法等手段来避免。此外,Linux内核还提供了一些检测和解决方法,如通过/sysfs下的文件system下的文件deadlock_detection来检测和解决。 总之,无论是Java还是Linux都是需要引起关注的问题,但通过合理的设计和调优,我们可以最大程度地避免的发生,并保证系统的稳定性和可靠性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值