线程中死锁的排查

本文通过一个具体的案例,深入解析了多线程编程中死锁的形成原因及排查方法。死锁是两个或多个线程因竞争资源而陷入无限等待的状态,文章详细展示了如何使用jps和jstack工具定位死锁问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在多线程编程过程中总是会遇到死锁的情况,但是死锁一旦出现,并不报错,也没提示,这种情况下,我们就得学会在线程出现死锁的时候进行排查。

什么叫做死锁:

死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。百度百科:死锁

我个人认识,死锁就是两个或者多个线程,彼此持有着对方需要使用的锁不释放,从而导致大家都不能进行下去,只能无限的等待。

死锁的排查:

首先写一个死锁的案例:

Task1.class:

package cn.mxl.task;

import java.util.concurrent.locks.ReentrantLock;

public class Task1 {
	private ReentrantLock lock1=new ReentrantLock();
	private ReentrantLock lock2=new ReentrantLock();
	public Task1(ReentrantLock lock1,ReentrantLock lock2){
		this.lock1=lock1;
		this.lock2=lock2;
	}
	public void deadThrea(){
		while(true){
			lock1.lock();
			System.out.println("第一层lock"+Thread.currentThread().getName());
			lock2.lock();
			System.out.println("第二层lock"+Thread.currentThread().getName());
			lock2.unlock();
			lock1.unlock();
		}
	}
}

Task2.class:

package cn.mxl.task;

import java.util.concurrent.locks.ReentrantLock;

public class Task2 {
	private ReentrantLock lock1=new ReentrantLock();
	private ReentrantLock lock2=new ReentrantLock();
	public Task2(ReentrantLock lock1,ReentrantLock lock2){
		this.lock1=lock1;
		this.lock2=lock2;
	}
	public void deadThrea(){
		while(true){
			lock2.lock();
			System.out.println("第一层lock"+Thread.currentThread().getName());
			lock1.lock();
			System.out.println("第二层lock"+Thread.currentThread().getName());
			lock1.unlock();
			lock2.unlock();
		}
	}
}

MyThread1.class:

package cn.mxl.task;


public class MyThread1 implements Runnable{
	Task1 task;
	public MyThread1(Task1 task){
		this.task=task;
	}
	public void run() {
		// TODO Auto-generated method stub
		task.deadThrea();
	}

}

MyThread2.class:

package cn.mxl.task;


public class MyThread2  implements Runnable{
	Task2 task;
	public MyThread2(Task2 task){
		this.task=task;
	}
	public void run() {
		// TODO Auto-generated method stub
		task.deadThrea();
	}
}

Run.class:

package cn.mxl.task;

import java.util.concurrent.locks.ReentrantLock;

public class Run {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		ReentrantLock lock1=new ReentrantLock();
		ReentrantLock lock2=new ReentrantLock();
		
		Task1 task1=new Task1(lock1, lock2);
		Task2 task2=new Task2(lock1, lock2);
		
		MyThread1 m1=new MyThread1(task1);
		MyThread2 m2=new MyThread2(task2);
		
		Thread t1=new Thread(m1);
		Thread t2=new Thread(m2);
		t1.start();
		t2.start();
	}

}

运行结果:

开始线程死锁排查:

使用 jps + jstack:

第一:在windons命令窗口,使用 jps -l (是小写的L) :

第二:查看端口:jstack -l 16456

运行结果:

已经说明出现了死锁现象;

第三: 使用JConsole:

 

然后就找到死锁位置了:

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值