@[toc]
什么是多线程死锁?
同步中嵌套同步,导致锁无法释放
多线程以及多进程改善了系统资源的利用率并提高了系统 的处理能力。然而,并发执行也带来了新的问题——死锁。所谓死锁是指多个线程因竞争资源而造成的一种僵局(互相等待),若无外力作用,这些进程都将无法向前推进。
1、系统资源的竞争
通常系统中拥有的不可剥夺资源,其数量不足以满足多个进程运行的需要,使得进程在运行过程中,会因争夺资源而陷入僵局,如磁带机、打印机等。只有对不可剥夺资源的竞争才可能产生死锁,对可剥夺资源的竞争是不会引起死锁的。
2、进程推进顺序不合适
进程在运行过程中,请求和释放资源的顺序不当,也同样会导致死锁。例如,并发进程 P1、P2分别保持了资源R1、R2,而进程P1申请资源R2,进程P2申请资源R1时,两者都会因为所需资源被占用而阻塞。
package com.yxl.demo.ThreadTest;
public class test5 {
public static void main(String[] args) throws InterruptedException {
TestDemo thread = new TestDemo();
Thread t1 = new Thread(thread,"窗口一");
Thread t2 = new Thread(thread,"窗口二");
t1.start();
Thread.sleep(40);
thread.flag = false;
t2.start();
}
}
class TestDemo implements Runnable{
//共享的火车票变量
private volatile int count = 100;
private Object object =new Object();
boolean flag = true;
//重寫run方法
@Override
public void run() {
if(flag){
while (count > 0) {
synchronized (object) {
sale();
}
}
}else{
while (count > 0) {
sale();
}
}
}
public synchronized void sale() {
try {
Thread.sleep(50);
}catch (Exception e){
}
synchronized (object) {
if (count > 0) {
System.out.println(Thread.currentThread().getName() + "出售 :" + (100 - count + 1));
count--;
}
}
}
/*
public void sale(){
synchronized (object){
if(count > 0){
System.out.println(Thread.currentThread().getName() +"出售 :" +(100 - count + 1));
count--;
}
}
}*/
}
执行结果:如图所示,红灯一直亮着,锁一直没释放,导致死锁的发生,程序卡住
t1 先获取object锁,在获取this锁,
t2 先获取this锁 ,在获取object锁
如何解决死锁的发生
- 加锁顺序(线程按照一定的顺序加锁)
- 加锁时限(线程尝试获取锁的时候加上一定的时限,超过时限则放弃对该锁的请求,并释放自己占有的锁)
- 死锁检测