美文网首页
写一个可以产生死锁的 Java 程序

写一个可以产生死锁的 Java 程序

作者: jyjz2008 | 来源:发表于2019-04-07 12:48 被阅读0次

参考文章

码农翻身 一书中的第一个故事“我是一个线程”

思路

如果有两个锁 L1 L2, 线程 t1 持有 L1 且在尝试获取 L2, 线程 t2 持有 L2 且在尝试获取 L1 那么就会出现死锁了

程序

synchronized 语句块实现

我们可以在 class 对象上加锁
具体如下

public class DeadLock {

    public static void main(String[] args) throws Exception {
        class Naive implements Runnable {
            private final Class c1;
            private final Class c2;
            private String name;

            private Naive(String name, Class c1, Class c2) {
                this.name = name;
                this.c1 = c1;
                this.c2 = c2;
            }

            @Override
            public void run() {
                synchronized (c1) {
                    try {
                        // 让另一个线程有机会被调度, 这样另一个线程就有机会获得 c2 对应的锁了
                        Thread.sleep(1000);
                        System.out.println(String.format("%s acquired %s", name, c1));
                        synchronized (c2) {
                            System.out.println(String.format("%s acquired %s", name, c2));
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }
        Thread t1 = new Thread(new Naive("t1", Integer.class, String.class));
        Thread t2 = new Thread(new Naive("t2", String.class, Integer.class));
        t1.start();
        t2.start();
        t1.join();
        t2.join();
    }
}

运行结果如下


运行结果

ReentrantLock 来实现

也可以用 ReentrantLock 来实现,程序如下

package com.coder.rising;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class DeadLock {

    public static void main(String[] args) throws Exception {
        class Naive implements Runnable {
            private final Lock lock1;
            private final Lock lock2;
            private String name;

            private Naive(String name, Lock lock1, Lock lock2) {
                this.name = name;
                this.lock1 = lock1;
                this.lock2 = lock2;
            }

            @Override
            public void run() {
                lock1.lock();
                try {
                    // 让另一个线程有机会被调度, 这样另一个线程就有机会获得 lock2 对应的锁了
                    Thread.sleep(1000);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                System.out.println(String.format("%s acquired %s", name, lock1));
                lock2.lock();
                System.out.println(String.format("%s acquired %s", name, lock2));
                lock2.unlock();
                lock1.unlock();
            }
        }
        Lock lock1 = new ReentrantLock();
        Lock lock2 = new ReentrantLock();
        Thread t1 = new Thread(new Naive("t1", lock1, lock2));
        Thread t2 = new Thread(new Naive("t2", lock2, lock1));
        t1.start();
        t2.start();
        t1.join();
        t2.join();
    }
}

运行结果如下


运行结果

相关文章

  • 写一个可以产生死锁的 Java 程序

    参考文章 码农翻身 一书中的第一个故事“我是一个线程” 思路 如果有两个锁 L1 L2, 线程 t1 持有 L1 ...

  • Java中死锁的定位与修复

    死锁应该可以说是并发编程中比较常见的一种情况,可以说如果程序产生了死锁那将会对程序带来致命的影响;所以排查定位、修...

  • 无标题文章

    Deadlock 1. 死锁产生: count = 10000: 2. 对上述程序产生死锁的解释: 关键字 syn...

  • Java死锁检测方式JConsole

    Java死锁检测方式之JConsole 我们在开发中应该尽量避免死锁,但是如果真的有死锁产生那么我们怎么在一个复杂...

  • 记一次Oracle死锁/阻塞排查

    1. 检查数据库确定 是否 真实存在死锁,若有 哪台机器哪个程序。 2. 确定死锁后,还可以检查是哪个语句产生死锁...

  • Java锁(悲观、乐观锁、CAS原子操作)

    Java死锁发生的必要条件 Java死锁产生的四个必要条件: 互斥使用,即当一个线程占用了资源,其他线程不能使用。...

  • Java Concurrent 死锁

    前言 死锁是一个比较大的概念,在并发场景下的加锁行为都有可能产生死锁问题。在Java 并发编程中会有死锁,操作系统...

  • Java死锁程序

    死锁大家都懂,这里提几个小知识点 1: 每个对象可作为监视器锁(Monitor),注意是对象,我们以对象引用作为锁...

  • 写一个 java 死锁玩玩

    java 死锁很容易遇到,睡不着 写一个 死锁上代码 简单明了的 死锁 。嘿嘿嘿! ok 我们看一下hotspo...

  • Java死锁检测之ThreadMXBean

    看此文章前请先了解之前一篇文章 "Java死锁之理解死锁" 中的死锁示例java 中提供了可以检测死锁的工具类Th...

网友评论

      本文标题:写一个可以产生死锁的 Java 程序

      本文链接:https://www.haomeiwen.com/subject/gyxsiqtx.html