• Java多线程之死锁问题


    Java多线程之死锁

    定义

    多个线程各自占有一些共享的资源,并且互相等待,直到获取到对方线程占有的资源本身才能够继续运行,而导致了两个或者两个以上的线程同时在无休止地等待对方释放资源,从而这些线程都处于停止状态。某一个同步块同时拥有两个以上对象的锁时,就可能发生死锁的情况。

    通俗理解:

    举个例子:两个小朋友手里分别有一颗糖,这两颗糖是不同味道的,并且这两个小朋友有都想尝尝另一颗糖果的味道,又不愿意放下自己手里的糖,形成了僵持状态。这就是死锁。

    产生死锁的四个必要条件

    • 互斥条件。一个资源每次只能被一个进程使用;

    • 请求与保持条件。一个进程因请求资源而阻塞时,对已获得的资源保持不放;

    • 不剥夺条件。进程已获得的资源,在未使用完之前,不能强行剥夺;

    • 循环等待条件。若干进程之间形成一种头尾相接的循环等待资源关系

    以上列出了死锁的四个必要条件,事实上只需要想办法打破其中任意一个多或多个条件,就可以避免死锁的发生。

    示例

    package 同步;

    public class lock {
       public static void main(String[] args) {
           Dress dress = new Dress(0,"魔仙女王");
           Dress dress1 = new Dress(1,"叶罗丽公主");

           new Thread(dress,"小魔仙").start();
           new Thread(dress1,"老魔仙").start();
      }
    }

    class Cloth{

    }

    class Jeans{

    }

    class Dress implements Runnable{
       static Cloth cloth = new Cloth();   //static修饰 意味着只有一件衣服
       static Jeans jeans = new Jeans();

       int choice;
       String user;

       public Dress(int choice, String user) {
           this.choice = choice;
           this.user = user;
      }

       @Override
       public void run() {
           try {
               dress();
          } catch (InterruptedException e) {
               e.printStackTrace();
          }
      }

    //   private void dress() throws InterruptedException { //此方法造成了死锁的发生
    //       if (choice == 0) {
    //           synchronized (cloth) {
    //               System.out.println(Thread.currentThread().getName() + "拿着衣服");
    //               Thread.sleep(1000);
    //               synchronized (jeans) {
    //                   System.out.println(Thread.currentThread().getName() + "拿着裤子");
    //               }
    //           }
    //       } else {
    //           synchronized (jeans) {
    //               System.out.println(Thread.currentThread().getName() + "拿着衣服");
    //               Thread.sleep(2000);
    //               synchronized (cloth) {
    //                   System.out.println(Thread.currentThread().getName() + "拿着裤子");
    //               }
    //           }
    //       }
    //   }

           private void dress() throws InterruptedException { //避免死锁发生的方法
           if (choice == 0) {
               synchronized (cloth) {
                   System.out.println(Thread.currentThread().getName() + "拿着衣服");
                   Thread.sleep(1000);

              }
               synchronized (jeans) {
                   System.out.println(Thread.currentThread().getName() + "拿着裤子");
              }
          } else {
               synchronized (jeans) {
                   System.out.println(Thread.currentThread().getName() + "拿着裤子");
                   Thread.sleep(2000);

              }
               synchronized (cloth) {
                   System.out.println(Thread.currentThread().getName() + "拿着衣服");
              }
          }
      }
    }

     

  • 相关阅读:
    创建异步Web服务
    MCAD考试计划
    微软面试题
    Reborn
    Qt项目注意事项
    在ASP.Net中两种利用CSS实现多界面
    为ASP.NET控件添加常用的JavaScript操作
    用Split函数分隔字符串
    Microsoft .NET Pet Shop 4.0
    搞定QString,string,char*,CString的互转
  • 原文地址:https://www.cnblogs.com/awong18/p/13157384.html
Copyright © 2020-2023  润新知