死锁
多线程以及多进程改善了系统资源的利用率并提高了系统的处理能力。然而,并发执行也带了新的问题-死锁。
所谓死锁是指多个线程因为竞争资源尔造成的一种僵局(互相等待),若无外力作用,这些线程都将无法推进
锁对象为Runnable接口实例对象的静态属性
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class test implements Runnable{
/**售卖票数*/
private int num;
/**锁对象1*/
private static Object obj1 = new Object();
/**锁对象2*/
private static Object obj2 = new Object();
public test(int num) {
this.num = num;
}
@Override
public void run() {
while(true) {
if(num == 1) {
synchronized (obj1) {
System.out.println(Thread.currentThread().getName()+"获得obj1,正在请求obj2");
try {
Thread.sleep(1000);
synchronized (obj2) {
System.out.println("获得obj1和obj2");
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}else {
synchronized (obj2) {
System.out.println(Thread.currentThread().getName()+"获得ibj2,正在请求obj1");
synchronized (obj1) {
System.out.println("获得obj1和obj2");
}
}
}
}
}
死锁产生的必要条件
- 互斥条件:线程要求对所分配的资源进行排他性控制,即在一段时间内某资源仅为一个线程所占有,此时若有其他线程请求该资源,则请求线程只能等待
- 不可剥夺条件:线程所获得的资源在未使用完毕之前,不能被其他线程强行夺走,即只能由获得该资源的线程自己来释放(只能是主动释放)
- 请求与保持条件:线程已经保持了至少一个资源,但又提出了新的资源请求,而该资源已经被其他线程所占有,此时请求被阻塞,但对自己已获得的资源保持不变
- 循环等待条件:存在一种线程资源的循环等待链,链中每一个线程已经获得的资源同时被链中下一个线程所请求,即存在一个处于等待状态的线程集合{p1,p2,p3...pn,p1,p2,p3..},其中pi等待的资源被p(i+1)所占有(i=1,,2,3...n-1)pn就是被pi所占有
死锁处理
-
预防死锁:通过设置某些限制条件,去破坏产生死锁的四个必要条件中的一个或者几个条件,来防止死锁的发生
-
破坏“互斥条件” :”互斥“条件是无法破坏的,因此,在死锁预防里主要是破坏其他几个必要条件,而不去设计破坏”互斥“条件
-
破坏“占有并等待”条件:就是在系统中不允许线程在已获得某中资源的情况下,申请其他的资源,即要想出一个办法,组织线程在持有资源的同时申请其他资源
-
方法一:一次性分配资源,即创建线程时,要求它申请所需的全部资源,系统或满足其所有要求,或什么也不给它
-
方法二:要求每个线程提出新的资源申请前,释放它所占有的资源。这样,一个线程在需要资源s时,必须先把它先前资源r释放掉,然后才能提出对s的申请,即使它可能很快又要用到资源r
这两种方法都巨大很大的局限性
-
-
破坏“不可抢占”条件:即允许其他线程对资源进行抢夺
-
方法一:如果占有某些资源的一个线程进行下一步资源请求被拒绝,则该线程必须释放它最初占有的资源,如果有必要,可再次请求这些资源和另外的资源
-
方法二:如果一个线程请求当前被另一个线程占有的一个资源,则操作系统可以抢占另一个线程的,要求它释放资源,只有在任意两个线程的优先级都不相同的条件下,方法二才能预防死锁
-
-
破坏“循环等待条件”:是将系统中的所有资源统一编号,线程可在任何时刻提出资源申请,但所有申请必须按照资源的编号顺序(默认升序)提出,这样就能保证系统不出现死循环
-
-
避免死锁:在资源的动态分配过程中,用某种方法去防止系统进入不安全状态,从而避免死锁的发生
-
检测死锁:允许系统在运行过程中发生死锁,但可设置检测机构及时检测死锁的发生,并采取适当措施加以清除
-
解除死锁:当检测出死锁后,便采取适当措施将进程从死锁状态中解脱出来
浙公网安备 33010602011771号