zoukankan      html  css  js  c++  java
  • 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() + "拿着衣服");
              }
          }
      }
    }

     

  • 相关阅读:
    什么是首次适应算法,该算法的特点是什么?
    用上、下界防护方法是如何实现界地址保护?在硬件上需要什么支持?
    什么是存储保护?
    什么是静态地址重定位,它需要什么支持?什么是动态地址重定位,他需要什么支持?静态地址重定位与动态地址重定位有什么区别?
    什么是逻辑地址,什么是物理地址,为什么要进行二者的转换工作?
    三个进程共享四个同类资源,这些资源的分配与释放只能一次一个。已知每一个进程最多需要两个资源,试问,该系统会发生死锁吗?为什么?
    试举出一种一种避免死锁的发生的方法,并说明为什么能避免死锁的发生?
    产生死锁的原因是什么?产生死锁的必要条件是什么?
    什么是死锁,试举例说明?
    说出两种一笔调度的算法,并说出这两种移臂调度算法的定义。
  • 原文地址:https://www.cnblogs.com/awong18/p/13157384.html
Copyright © 2011-2022 走看看