社区微信群开通啦,扫一扫抢先加入社区官方微信群
社区微信群
实现一个最简单的死锁(Java版)
/**
* @author wall
* @date 2019/7/29 16:42
* @description 实现一个死锁:A线程获取B线程占有的锁,B线程获取A线程占有的锁
*/
public class DeadLock {
//定义两把锁
private static ReentrantLock lockA = new ReentrantLock();
private static ReentrantLock lockB = new ReentrantLock();
//测试
public static void main(String[] args) {
//启动线程A,B
new Thread(new A()).start();
new Thread(new B()).start();
}
static class A implements Runnable{
@Override
public void run() {
Thread.currentThread().setName("A线程");
//获取锁A
lockA.lock();
System.out.println(Thread.currentThread().getName()+"获取锁A");
//模拟业务操作
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//再获取锁B
lockB.lock();
System.out.println(Thread.currentThread().getName()+"获取锁B");
lockA.unlock();
lockB.unlock();
}
}
static class B implements Runnable{
@Override
public void run() {
Thread.currentThread().setName("B线程");
//获取锁B
lockB.lock();
System.out.println(Thread.currentThread().getName()+"获取锁B");
//模拟业务操作
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//再获取锁A
lockA.lock();
System.out.println(Thread.currentThread().getName()+"获取锁A");
}
}
}
产生死锁的四大必要条件
①资源互斥/资源不共享
互斥条件:一个资源每次只能被一个进程使用。
②占有和等待/请求并保持
(请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
③资源不可剥夺
进程已获得的资源,在末使用完之前,不能强行剥夺。
④环路等待
若干进程之间形成一种头尾相接的循环等待资源关系。
举个例子▼
小明有键盘,小白有鼠标,小明要用电脑打游戏,小白要用电脑做PPT,小明没有鼠标没法打游戏,小白没有键盘没法做PPT,小明等小白把鼠标给自己,小白也等小明把键盘给自己,但是小明不愿意把键盘给小白,小白也不愿意把鼠标给小明,小明和小白也不能互相抢键盘和鼠标,他俩之间就形成了死锁。
避免死锁的方式
死锁的解除
1、资源剥夺法
挂起某些死锁进程,并抢占它的资源,将这些资源分配给其他的死锁进程。但应防止被挂起的进程长时间得不到资源,而处于资源匮乏的状态。
2、撤销进程法
强制撤销部分、甚至全部死锁进程并剥夺这些进程的资源。撤销的原则可以按进程优先级和撤销进程代价的高低进行。
3、进程回退法
让一(多)个进程回退到足以回避死锁的地步,进程回退时自愿释放资源而不是被剥夺。要求系统保持进程的历史信息,设置还原点。
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!