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() + "拿着衣服");
              }
          }
      }
    }

     

  • 相关阅读:
    批量重命名工具 Bulk Rename Utility
    Makefile中的ifeq 多条件使用
    利用Python批量下载邮件附件
    在线随机抽取工具、在线汉字转拼音
    《如何把事情做到最好》读书笔记
    Android 通过adb快速恢复出厂设置
    Makefile的ifeq逻辑或,逻辑与的变通实现
    Android 获取后台正在运行的第三方应用列表
    Android.mk 中 filter 和 filterout 的用法
    Android TV端电视直播软件 和 投屏工具
  • 原文地址:https://www.cnblogs.com/awong18/p/13157384.html
Copyright © 2011-2022 走看看