zoukankan      html  css  js  c++  java
  • 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不推荐使用该方法来暂停线程。

    温故而知新
  • 相关阅读:
    node代码打包为 exe文件---端口进程关闭demo
    java 中几种常用数据结构
    Java 多线程编程
    【java排序】 归并排序算法、堆排序算法
    【java排序】 选择排序,插入排序,希尔算法
    【java排序】冒泡排序、快速排序
    springMVC执行流程及原理
    Java反射机制详解
    【Java并发编程】:并发新特性—信号量Semaphore
    【Java并发编程】:并发新特性—障碍器CyclicBarrier
  • 原文地址:https://www.cnblogs.com/Uzai/p/9679001.html
Copyright © 2011-2022 走看看