目录
什么是死锁?
多线程在运行期间,都需要获取对方线程所持有的锁,导致形成相互等待的局面,形成死锁。
package com.apesource.Demo3;
public class Counter {
private static Object lockA = new Object();
private static Object lockB = new Object();
public void add() throws InterruptedException {
synchronized (lockA) { // 获得lockA的锁
Thread.sleep(100); // 线程休眠,不会释放lockA
synchronized (lockB) { // 获得lockB的锁
System.out.println("执行add()");
} // 释放lockB的锁
} // 释放lockA的锁
}
public void dec() throws InterruptedException {
synchronized (lockB) { // 获得lockB的锁
Thread.sleep(100);
synchronized (lockA) { // 获得lockA的锁
System.out.println("执行dec()");
} // 释放lockA的锁
} // 释放lockB的锁
}
}
产生死锁的四个条件是什么?
1. 资源互斥:对所分配的资源进行排它性控制,锁在同一时刻只能被一个线程使用;
2. 不可剥夺:线程已获得的资源在未使用完之前,不能被剥夺,只能等待占有者自行释放锁;
3. 请求等待:当线程因请求资源而阻塞时,对已获得的资源保持不放。
4. 循环等待:线程之间的相互等待。
如何避免死锁?
1.每次只占用不超过一个锁
2.设置特定的执行顺序
3.设置优先级
4.使用信号量
package com.apesource.Demo3;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
//使用信号量解决死锁问题
public class Deadlock {
private Semaphore semaphoreA = new Semaphore(1);
private Semaphore semaphoreB = new Semaphore(1);
public void add() throws InterruptedException {
while(semaphoreA.tryAcquire(1,TimeUnit.SECONDS)) {
Thread.sleep(1000);
if(semaphoreB.tryAcquire(1,TimeUnit.SECONDS)) {
try {
System.out.println("执行add()");
return;
}finally {
semaphoreA.release();
semaphoreB.release();
}
}else {
semaphoreA.release();
semaphoreB.release();
}
}
}
public void dec() throws InterruptedException {
while(semaphoreB.tryAcquire(1,TimeUnit.SECONDS)) {
Thread.sleep(1000);
if(semaphoreA.tryAcquire(1,TimeUnit.SECONDS)) {
try {
System.out.println("执行dec()");
return;
}finally {
semaphoreB.release();
semaphoreA.release();
}
}else {
semaphoreB.release();
semaphoreA.release();
}
}
}
}