zoukankan      html  css  js  c++  java
  • 理解死锁的概念(实例)

     1 package com.lijunwei.nov13;
     2 
     3 public class A {
     4     public synchronized void foo(B b) {
     5         System.out.println("当前线程名:" + Thread.currentThread().getName() + " 进入了A实例的foo()方法"); //
     6         try {
     7             Thread.sleep(200);
     8         } catch (InterruptedException e) {
     9             e.printStackTrace();
    10         }
    11 
    12         System.out.println("当前线程名:" + Thread.currentThread().getName()+" 企图调用B实例的last()方法"); //
    13         b.last();
    14     }
    15 
    16     public synchronized void last() {
    17         System.out.println("进入了A实例的last()方法");
    18     }
    19 
    20 
    21 }
     1 package com.lijunwei.nov13;
     2 
     3 public class B {
     4 
     5     public synchronized void bar(A a) {
     6         System.out.println("当前线程名:" + Thread.currentThread().getName() + " 进入了B实例的bar()方法"); //
     7         try {
     8             Thread.sleep(200);
     9         } catch (InterruptedException e) {
    10             e.printStackTrace();
    11         }
    12 
    13         System.out.println("当前线程名:" + Thread.currentThread().getName()+" 企图调用A实例的last()方法"); //
    14         a.last();
    15     }
    16 
    17     public synchronized void last() {
    18         System.out.println("进入了B实例的last()方法");
    19     }
    20 
    21 
    22 }
    package com.lijunwei.nov13;
    
    public class DeadLockTest implements Runnable {
        private A a = new A();
        private B b = new B();
    
        public void init() {
            Thread.currentThread().setName("Main Thread...");
            // 调用a对象的foo()方法
            a.foo(b);
            System.out.println("进入了主线程之后...");
        }
        
        @Override
        public void run() {
            Thread.currentThread().setName("Sub Thread...");
            // 调用b对象的bar()方法
            b.bar(a);
            System.out.println("进入了副线程后");
        }
    
        public static void main(String[] args) {
            // main thread
            DeadLockTest deadLockTest = new DeadLockTest();
            // sub thread
            new Thread(deadLockTest).start();
    
            deadLockTest.init();
        }
    }

    ref:疯狂java讲义第五版 p757
    死锁产生过程的分析:
    程序中A、B对象的方法都是同步方法,也就是说A对象和B对象都是同步锁。程序中有两个线程执行副线程的线程执行体是DeadLockTest里的main()方法(main方法调用了init方法)。其中run方法中让B对象调用bar()方法,init()方法让A对象调用foo()方法。图中显示先执行了init()方法,调用了A对象的foo()方法,进入foo()方法前该线程对A对象加锁——当程序执行到①代码时,主线程暂停了200ms;CPU切换至另一个线程,注意sleep方法并不会释放锁另一个线程让B对象执行bar()方法,所以看到副线程开始执行B对象的bar()方法,进入bar()方法之前该线程对B对象加锁——当程序执行到②时,副线程也暂停200ms;接下来主线程会先醒过来,继续向下执行。直到③处代码需要调用B对象的last()方法——执行该方法需要对B对象加锁,而此时副线程持有B对象的锁,因此主线程被阻塞;接下来副线程也醒过来了并继续向下执行,知道④处需要调用A对象的last()方法——执行该方法需要对A对象加锁,而此时主线程持有A对象的锁,因此副线程被阻塞。至此,就出现了主线程保持着A对象的锁,等待对B对象加锁,副线程保持着B对象的锁,等待对A对象加锁,两个线程互相等待对方先释放,出现死锁现象。

  • 相关阅读:
    HTML5中的audio在手机端和 微信端的自动播放
    vue框架
    购物车原理
    angular前端框架
    -webkit-line-clamp超过两行就出现省略号
    jQuery事件委托
    淘宝橱窗
    选字游戏
    大众点评订单分库分表实践
    业界难题-“跨库分页”的四种方案
  • 原文地址:https://www.cnblogs.com/leejunwei/p/thread00.html
Copyright © 2011-2022 走看看