死锁是指两个或两个以上的进程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们将无法推进下去,此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等地啊的进程称为死锁进行。本实例模拟两个人就餐在等待一双筷子时引起的死锁。
模拟等待筷子没法吃饭引起的死锁现象的技术要点如下:
(1)产生死锁的原因主要有:因为系统资源不足,进程运行推进的顺序不合适,资源分配不相等。如果系统资源充足,进程的资源请求都能够得到满足,死锁出现的可能性就很低,否则就会因争夺有限资源而陷入死锁。
(2)产生死锁的四个必要条件:一是互斥条件,一个资源每次只能被一个进程使用;二是请求与保持条件,一个进程因请求资源而阻塞时,对已获得的资源保持不放;三是不剥夺条件,进程已获得的资源,在未使用完之前,不能强行剥夺;四是循环等待条件,若干进程之间形成一种头尾相接的循环等待资源关系。这四个条件是死锁的必要条件,只要系统发生死锁,这些条件必然成立,而只要上述条件之一不满足,就不会发生死锁。
package core;
public class TextDeadLock {
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[1]) {//在同一时间只能有一个类访问
System.out.println("乙拿起了 "+chopsticks[1]+" 在等待另一" +chopsticks[0]);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println("线程休眠出错: "+e.getMessage());
}
synchronized (chopsticks[0]) {
System.out.println("乙又拿起了 "+chopsticks[0]);
}
}
}
}
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();//守护线程
}
}
源程序解读
(1)TextDeadLock类创建静态字符串数组,用来存放所需的筷子。创建静态内部类firstThread运用同步快synchronized()来实现在同一时间只能有一个线程访问。在其同步块中再次使用同步块。甲在拿起“筷子1”然后等待“筷子2”。静态内部类secondThread运用同步快synchronized()使得乙拿起“筷子2”然后等待“筷子1”。
(2)主程序中调用了守护线程类DaemonThread,守护线程必须等待所有的非守护线程都退出后它才能退出,看控制台输出,firstThread 和secondThread互相等地啊筷子资源,造成死锁,则守护线程一直运行。