一、死锁的定义
所谓死锁是指两个或两个以上的线程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。
二、死锁产生的原因
1.资源有限;
2.锁嵌套;
3.不强制剥夺线程占有的资源。
三、死锁案例代码:
以扫描仪和打印机为例,有多个线程争夺这两个共享资源的使用权
打印机类:
package cc.zxf.owner.vip.lineLock;
/**
* 打印机类
*/
public class Print {
public void printing(){
System.out.println("打印机开始工作!!!!!");
}
}
扫描仪类:
package cc.zxf.owner.vip.lineLock;
/**
* 扫描仪类
*/
public class Scan {
public void scaning(){
System.out.println("扫描仪开始工作!!!!!");
}
}
测试类:
package cc.zxf.owner.vip.lineLock;
/**
* 线程死锁
*/
public class TestDeadLock {
private static Print print = new Print();
private static Scan scan = new Scan();
private static class work1 extends Thread{
@Override
public void run() {
System.out.println("线程:"+Thread.currentThread().getId()+" 开始获取扫描仪!!");
synchronized (scan){
scan.scaning();
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程:"+Thread.currentThread().getId()+" 开始获取打印机!!");
synchronized (print){
print.printing();
}
}
}
}
private static class work2 extends Thread{
@Override
public void run() {
System.out.println("线程:"+Thread.currentThread().getId()+" 开始获取打印机!!");
synchronized (print){
print.printing();
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程:"+Thread.currentThread().getId()+" 开始获取扫描仪!!");
synchronized (scan){
scan.scaning();
}
}
}
}
public static void main(String[] args){
work1 work1 = new work1();
work2 work2 = new work2();
work1.start();
work2.start();
}
}
执行结果:
四、如何避免死锁:
1、让程序每次至多只能获得一个锁。
2、设计时考虑清楚锁的顺序,尽量减少嵌套的加锁交互数量。
3、既然死锁的产生是两个线程无限等待对方持有的锁,那么只要在等待时间上加个上限就好了。