• java 多线程 7 : 死锁


    两个线程互相等待对方释放同步监视器就会发生死锁

    public class A {
    
        public synchronized void foo(B b) {
            System.out.println("当前线程:" + Thread.currentThread().getName() + "进入A实例的foo方法");
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("当前线程:" + Thread.currentThread().getName() + "企图调用B实例的last方法");
            b.last();
        }
        
        public synchronized void last() {
            System.out.println("进入到A的last方法");
        }
    }
    public class B {
    
        public synchronized void bar(A a) {
            System.out.println("当前线程:" + Thread.currentThread().getName() + "进入B的bar方法");
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("当前线程:" + Thread.currentThread().getName() + "企图调用A实例的last方法");
            a.last();
        }
        
        public synchronized void last(){
            System.out.println("进入B的last方法内");
        }
    }
    public class DeadLock implements Runnable{
        A a = new A();
        B b = new B();
        
        public void init() {
            Thread.currentThread().setName("主线程");
            a.foo(b);
            System.out.println("进入主线程之后");
        }
        
        @Override
        public void run() {
            Thread.currentThread().setName("副线程");
            b.bar(a);
            System.out.println("进入副线程之后");
        }
    
        public static void main(String[] args) {
            DeadLock dl = new DeadLock();
            new Thread(dl).start();
            dl.init();
        }
    }

    结果分析:

    副线程先执行 —— b调用bar() —— 进入bar方法前“副线程”对B对象加锁 —— 执行sleep,睡2s —— cpu切换执行到另一个线程

    主线程开始执行 —— a调用foo() —— 进入foo方法前“主线程”对A对象加锁 —— 执行sleep,睡2s —— cpu切换执行到另一个线程(此时副线程醒了)

    副线程醒了继续向下执行 —— 企图调用A实例的last同步方法 —— 但是此时主线程保持着对A对象的加锁,那么副线程就等待主线程对A的释放,等待......

    主线程2s过后也醒了 ,继续向下执行 —— 企图调用B实例的last同步方法 —— 但是副线程仍然保持着对B对象的加锁,主线程等待副线程对B的释放,等待......

    相互等待 , 就耗着了  , 死锁。

    注意: Thread的suspend() 方法很容易导致死锁 , java不推荐使用该方法来暂停线程。

    温故而知新
  • 相关阅读:
    他扎根农村种植双孢菇,从门外汉成为了“土专家”
    农村小伙成立生态农业基地,带领村民打开致富新门路
    小伙让蜜柚成为真正的“黄金柚”,帮助600多农户发家致富
    js时间格式化函数,支持Unix时间戳
    js时间格式化函数,支持Unix时间戳
    js时间格式化函数,支持Unix时间戳
    js时间格式化函数,支持Unix时间戳
    Netty随记之ChannelInboundHandlerAdapter、SimpleChannelInboundHandler
    Netty随记之ChannelInboundHandlerAdapter、SimpleChannelInboundHandler
    Netty随记之ChannelInboundHandlerAdapter、SimpleChannelInboundHandler
  • 原文地址:https://www.cnblogs.com/Uzai/p/9679001.html
Copyright © 2020-2023  润新知