死锁有一系列的方法可以避免,也有很多的判断和解决办法,在上一个实例中遇到的没法吃饭的死锁问题,解决办法有很多。例如,再增加一只筷子,甲或者乙可以拿到新增的筷子开始吃饭,吃完饭后将筷子资源释放,然后另一个人可以开始吃饭;又或者是甲和乙都先拿起筷子1后拿起筷子2就不会有死锁问题,本实例就是采用后一种方式。
解决死锁问题方便吃饭的技术要点
死锁排除方法:一是撤销陷入死锁的全部进程;二是逐个撤销陷于死锁的进程,直到死锁不存在;三是从陷于死锁的进程中逐个强迫放弃所占用的资源,直至死锁消失;四是从另外一些进程那里强行剥夺足够数量的资源分配给死锁进程,以解除死锁状态。
预防死锁需要防止进程在处于等待状态下的情况下占用资源,在系统运行过程中国,对进程发出的每一个系统能够满足的资源申请进行动态检查,并根据检查结果决定是否分配资源,若分配资源后系统可能发生死锁,则不予分配,否则便分配。因此,对资源的分配要给予合理的规划。
package core;
public class TextSolveDeadLock {
static String[] chopsticks=new String[]{"筷子1","筷子2"};
static class firstThread extends Thread{
public void run(){
synchronized (chopsticks[0]) {//在同一时间只能有一个类访问
System.out.println("甲拿起了 "+chopsticks[0]+" 在等待另一" +chopsticks[1]);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println("线程休眠出错: "+e.getMessage());
}
synchronized (chopsticks[1]) {
System.out.println("甲又拿起了 "+chopsticks[1]);
}
}
}
}
static class secondThread extends Thread{
public void run(){
synchronized (chopsticks[0]) {//在同一时间只能有一个类访问
System.out.println("乙拿起了 "+chopsticks[0]+" 在等待另一" +chopsticks[1]);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println("线程休眠出错: "+e.getMessage());
}
synchronized (chopsticks[1]) {
System.out.println("乙又拿起了 "+chopsticks[1]);
}
}
}
}
static class DaemonThread extends Thread{
public DaemonThread(){
this.setDaemon(true);
}
public void run(){
while(true){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println("线程休眠出错: "+e.getMessage());
}
System.out.println("守护线程:程序正在运行...");
}
}
}
public static void main(String[] args) {
firstThread first=new firstThread();
secondThread second=new secondThread();
DaemonThread daemon=new DaemonThread();
first.start();
second.start();
daemon.start();//守护线程
}
}
源程序解读
TextSolveDeadLock类中的静态内部类firstThread拿起了“筷子1”,又拿起了“筷子2”。同时secondThread拿起“筷子1”,在等待”筷子2“,这样便解决了死锁问题。