在多线程编程过程中总是会遇到死锁的情况,但是死锁一旦出现,并不报错,也没提示,这种情况下,我们就得学会在线程出现死锁的时候进行排查。
什么叫做死锁:
死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。百度百科:死锁。
我个人认识,死锁就是两个或者多个线程,彼此持有着对方需要使用的锁不释放,从而导致大家都不能进行下去,只能无限的等待。
死锁的排查:
首先写一个死锁的案例:
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:
然后就找到死锁位置了: