首页 > 编程 > Java > 正文

Java模拟死锁发生之演绎哲学家进餐问题案例详解

2019-11-26 08:27:07
字体:
来源:转载
供稿:网友

本文实例讲述了Java模拟死锁发生之演绎哲学家进餐问题。分享给大家供大家参考,具体如下:

一 点睛

常见的死锁形式:当线程1已经占据资源R1,并持有资源R1上的锁,而且还在等待资源R2的锁;而线程2已经占据资源R2,并且持有资源R2上的锁,却正在等待资源R1上的锁。如果两个线程不释放自己占据的资源锁,而且还申请对方资源上的锁,申请不到时只能等待,而且它们只能永远的等待下去。

二 实战

1 代码

public class DeadLockDemo{  /** knife锁 */  private static String knife = "餐刀"; //临界资源  /** fork锁 */  private static String fork = "叉子"; //临界资源  public static void main(String[] args)  {    DaemonThread daemonTh = new DaemonThread();    Thread newDaemon = new Thread(daemonTh);    newDaemon.setDaemon(true);    newDaemon.start();    new DeadLockDemo().deadLock();  }  private void deadLock()  {    Thread t1 = new Thread(new Runnable() {      @Override      public void run()      {        synchronized (knife) {          System.out.println(Thread.currentThread().getName() + "拿起了" + knife + ", 等待" + fork + "......");          try {            Thread.sleep(2000);          } catch (InterruptedException e) {            e.printStackTrace();          }          synchronized (fork) {            System.out.println(Thread.currentThread().getName() + "又拿起了" + fork + ",吃饭中...");          }        }      }    });    Thread t2 = new Thread(new Runnable() {      @Override      public void run() {        synchronized (fork) {          System.out.println(Thread.currentThread().getName() + "拿起了" + fork + ", 等待" + knife + "......");          synchronized (knife) {            System.out.println(Thread.currentThread().getName() + "又拿起了" + knife + ",吃饭中...");          }        }      }    });    t1.start();    t2.start();  }}class DaemonThread implements Runnable{  @Override  public void run()  {    while(true)    {      try {        Thread.sleep(1000);      }catch (InterruptedException e) {        e.printStackTrace();      }      System.out.println("守护线程:程序仍在运行中...");    }  }}

2 运行

Thread-1拿起了餐刀, 等待叉子......
Thread-2拿起了叉子, 等待餐刀......
守护线程:程序仍在运行中...
守护线程:程序仍在运行中...
守护线程:程序仍在运行中...
守护线程:程序仍在运行中...
守护线程:程序仍在运行中...

三 预防死锁

1 解决方法

如果规定线程A和B都必须先拿刀,再拿叉,就不会发生死锁。

2 代码

public class DeadLockDemo{  /** knife锁 */  private static String knife = "餐刀"; //临界资源  /** fork锁 */  private static String fork = "叉子"; //临界资源  public static void main(String[] args)  {    DaemonThread daemonTh = new DaemonThread();    Thread newDaemon = new Thread(daemonTh);    newDaemon.setDaemon(true);    newDaemon.start();    new DeadLockDemo().deadLock();  }  private void deadLock()  {    Thread t1 = new Thread(new Runnable() {      @Override      public void run()      {        synchronized (knife) {          System.out.println(Thread.currentThread().getName() + "拿起了" + knife + ", 等待" + fork + "......");          try {            Thread.sleep(2000);          } catch (InterruptedException e) {            e.printStackTrace();          }          synchronized (fork) {            System.out.println(Thread.currentThread().getName() + "又拿起了" + fork + ",吃饭中...");          }        }      }    });    Thread t2 = new Thread(new Runnable() {      @Override      public void run() {        synchronized (knife) {          System.out.println(Thread.currentThread().getName() + "拿起了" + knife + ", 等待" + fork + "......");          synchronized (fork) {            System.out.println(Thread.currentThread().getName() + "又拿起了" + fork + ",吃饭中...");          }        }      }    });    t1.start();    t2.start();  }}class DaemonThread implements Runnable{  @Override  public void run()  {    while(true)    {      try {        Thread.sleep(1000);      }catch (InterruptedException e) {        e.printStackTrace();      }      System.out.println("守护线程:程序仍在运行中...");    }  }}

3 运行

Thread-1拿起了餐刀, 等待叉子......
守护线程:程序仍在运行中...
守护线程:程序仍在运行中...
Thread-1又拿起了叉子,吃饭中...
Thread-2拿起了餐刀, 等待叉子......
Thread-2又拿起了叉子,吃饭中...

更多java相关内容感兴趣的读者可查看本站专题:《Java进程与线程操作技巧总结》、《Java数据结构与算法教程》、《Java操作DOM节点技巧总结》、《Java文件与目录操作技巧汇总》和《Java缓存操作技巧汇总

希望本文所述对大家java程序设计有所帮助。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表