Java多线程 死锁代码demo

文章目录

死锁代码demo

如下的代码为死锁的demo.
创建了两个线程, 分别拥有锁o1和o2 ,并且尝试去获取锁o2和o1 ,造成相互等待的阻塞状态.

package com.thread.deadlock;

/**
 * 类名称:MustDeadLock
 * 类描述:   必定发生死锁的情况
 *
 * @author: https://javaweixin6.blog.csdn.net/
 * 创建时间:2020/9/8 7:55
 * Version 1.0
 */
public class MustDeadLock implements Runnable {
    //标记位, 不同的线程根据标记位执行不同的代码
    int flag = 1 ;

    //两把锁
    static Object o1 = new Object();
    static Object o2 = new Object();

    public static void main(String[] args) {
        MustDeadLock r1 = new MustDeadLock();
        MustDeadLock r2 = new MustDeadLock();
        //给不同的线程, 设置不同的标记位
        r1.flag=1;
        r2.flag=2;

        Thread t1 = new Thread(r1);
        Thread t2 = new Thread(r2);
        t1.start();
        t2.start();
    }

    @Override
    public void run() {
        //打印出标记位
        System.out.println("flag = "+flag);
        if (flag == 1) {
            synchronized (o1) {

                try {
                    //线程1持有锁o1, 并且等待500ms ,让线程2执行
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                //线程1尝试去获取锁o2
                synchronized (o2) {
                    System.out.println("线程1成功拿到两把锁");
                }

            }
        }

        if (flag == 2) {

            synchronized (o2) {

                try {
                    //持有锁o2, 并且等待500ms ,让线程1执行
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                //线程2尝试去获取锁o1
                synchronized (o1) {
                    System.out.println("线程2成功拿到两把锁");
                }
            }
        }
    }

}

打开控制台, 程序运行如下, 红色的灯一直亮着, 代表程序一直在后台运行中, 并没有结束.此时进入了死锁的状态.

死锁分析:
当线程1的flag=1, 先锁定了锁o1 ,睡眠500ms , 然后尝试去获取锁o2.

而线程1在睡眠的时候, 另一个线程2的flag=2 的线程启动, 锁定了o2 ,睡眠了500ms , 等待线程 1 去释放锁o1 .

线程1睡眠结束后, 发现需要锁o2才能继续执行接下来的代码, 但是此时锁o2已经被线程2所持有锁定, 线程2睡眠结束后, 发现需要锁o1才能继续执行, 而此时锁o1已经被线程1锁定.

此时线程1和2就进入了相互等待的阶段. 持有对方想拿到的锁, 又想拿到对方持有的锁

此时如果点击控制台的红色按钮强制退出 可以看到退出码为-1 ,代表为不正常的退出, 应该避免不正常的退出, 否则可能造成数据丢失等情况. 正常退出为0 .

猜你喜欢

转载自blog.csdn.net/qq_33229669/article/details/108460550