标签:ack 演示 art 打印 资源释放 申请 拒绝 相互 strong
多个线程因竞争资源而造成的一种僵局(互相等待),无外力作用下程序无法推进的情况称之为死锁
如下图:线程P1拥有锁R1,请求锁R2,而线程P2拥有锁R2请求锁R1,彼此都请求不到资源,结束不了方法无法释放对方需要的资源,因此相互等待无法推进,这就是死锁
? 进程要求对所分配的资源进行排他性控制,即该资源只能被一个进程占用,其他请求的进程只能等待占用资源的进程结束,释放资源
? 进程已经获取了一个资源,在它使用完毕之前,无法被其他进程剥夺走,只能由获取该资源的进程主动释放资源
? 进程当前已经获取了一个资源,但又提出了一个新的资源请求,而新的资源被占用了,此时请求被阻塞, 当前获取的的资源也无法释放
? 多个进程呈环形互相等待的情况称为循环等待,出现死锁的时候一定是循环等待的情况,但是循环等待不一定就是死锁,但这个闭环中的某个进程请求的资源不仅仅只有一个请求途径,环形外有进程也释放它请求的资源,则可以跑出闭环,则不是死锁
以下实现一个死锁:
通过两个线程互相等待的情况来演示
public class Locks implements Runnable{
private int flag; //用来引导两个线程调用不同的资源
//这里要对两个锁定义static,必须是请求共享资源才会引发死锁
public static Lock lock = new ReentrantLock();
public static Lock lock2 = new ReentrantLock();
public Locks(int flag){
this.flag = flag;
}
public void run() {
if (flag==1) {
//请求锁1
lock.lock();
try {
System.out.println("线程1请求锁2");
//持有锁1的时候请求锁2
lock2.lock();
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
lock2.unlock();
}
}else{
lock2.lock();
try {
System.out.println("线程2请求锁1");
lock.lock();
Thread.sleep(1000);
} finally {
lock.unlock();
lock2.unlock();
}
}
}
}
创建启动线程进行测试:
public class Demo {
public static void main(String[] args) {
Thread thread = new Thread(new Locks(1));
Thread thread2 = new Thread(new Locks(2));
thread.start();
thread2.start();
}
}
发生死锁
死锁的预防是严格控制产生死锁的必要条件的存在,而避免是不严格控制,因为就算满足了必要条件也不一定会发生死锁,如果这样限制的话,系统的性能将会降低,因此通过一些更优的算法,来避免产生死锁,就算条件满足也不会发生死锁。
为所有资源统一编号,所有的线程在请求不同资源时都得按顺序请求
同类资源则要一次请求完毕,即同一台设备的机器打印机传真机要同时申请
举个例子:
现有两个进程P1,P2,两个资源R1,R2,P1和P2都要请求R1,R2,假设P1先获取到了R1,那么P2就不能先去请求R2,必须等待P1释放R1资源,以此来避免死锁
银行家算法结构的逻辑如下:
分析:
? 预防和避免死锁系统开销大且不能充分利用资源,更好的方法是不采取任何限制性措施,而是提供检测和解脱死锁的手段,这就是死锁的检测和恢复
死锁检测的数据结构
死锁检测步骤
标签:ack 演示 art 打印 资源释放 申请 拒绝 相互 strong
原文地址:https://www.cnblogs.com/JIATCODE/p/13276343.html