java - 寻求有关如何避免死锁的建议

标签 java multithreading deadlock

我的应用程序中也有类似的情况:

public class Example {

private static A aClass = new A();
private static B bClass = new B();

public static void main(String[] args) {

    new Thread(new Runnable() {
        @Override
        public void run() {
            bClass.start();
        }
    }, ">>>>>>>>>>").start();


    new Thread(new Runnable() {
        @Override
        public void run() {
            aClass.start();
        }
    }, "__________").start();

    try {
        Thread.sleep(200);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    detectDeadlock();
}

private static void detectDeadlock() {
    ThreadMXBean threadBean = ManagementFactory.getThreadMXBean();
    long[] threadIds = threadBean.findMonitorDeadlockedThreads();
    int deadlockedThreads = threadIds != null? threadIds.length : 0;
    System.out.println("Number of deadlocked threads: " + deadlockedThreads);
}

private static class A {
    private final Object aLock = new Object();

    public void start() {
        System.out.println(Thread.currentThread()+ " " + "A-start; waiting for aLock");
        synchronized (aLock) {
            System.out.println(Thread.currentThread()+ " " + "A-start; acquired aLock");
            bClass.synchronizedMethod();
        }
        System.out.println(Thread.currentThread()+ " " + "A-start; release aLock");
    }

    public void synchronizedMethod() {
        System.out.println(Thread.currentThread()+ " " + "A-synchronizedMethod; waiting for aLock");
        synchronized (aLock) {
            System.out.println(Thread.currentThread()+ " " + "A-synchronizedMethod; acquired aLock");
        }
        System.out.println(Thread.currentThread()+ " " + "A-synchronizedMethod; release aLock");
    }
}

private static class B {
    private final Object bLock = new Object();

    public void synchronizedMethod() {
        System.out.println(Thread.currentThread()+ " " + "B-synchronizedMethod; waiting for bLock");
        synchronized (bLock) {
            System.out.println(Thread.currentThread()+ " " + "B-synchronizedMethod; acquired bLock");
        }
        System.out.println(Thread.currentThread()+ " " + "B-synchronizedMethod; release bLock");
    }

    public void start() {
        System.out.println(Thread.currentThread() + " " + "B-Start; waiting for bLock");
        synchronized (bLock) {
            System.out.println(Thread.currentThread()+ " " + "B-Start; acquired bLock");
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            aClass.synchronizedMethod();
        }
        System.out.println(Thread.currentThread()+ " " + "B-Start; released bLock");
    }
}

}

此代码片段的输出将如下所示:

Thread[>>>>>>>>>>,5,main] B-Start; waiting for bLock
Thread[>>>>>>>>>>,5,main] B-Start; acquired bLock
Thread[__________,5,main] A-start; waiting for aLock
Thread[__________,5,main] A-start; acquired aLock
Thread[__________,5,main] B-synchronizedMethod; waiting for bLock
Thread[>>>>>>>>>>,5,main] A-synchronizedMethod; waiting for aLock
Number of deadlocked threads: 2

我正在寻找有关这种僵局情况的一些指导。

您能告诉我如何避免这种僵局吗?

最佳答案

最后我选择使用由 A 和 B 实例共享的全局锁。

代码看起来像这样:

 private static class Lock {
    private static Lock lock = new Lock();
    private Lock(){}
    public static Lock getLock() {return lock;}
}

private static class A {
    private final Object aLock = Lock.getLock();
    // ...
}

private static class B {
    private final Object bLock = Lock.getLock();
    // ...
}

关于java - 寻求有关如何避免死锁的建议,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53304022/

相关文章:

java - android - 获取远程 JSON 会引发错误

Java 脚本存储和加载状态

java - Java EE 应用程序中的线程死锁

java - 使用 MySQL 查询的结果更新 TableView 行颜色

c++ - 从C++中的2个不同线程访问属于同一对象的不同数据成员

.net - WCF ConcurrencyMode.Multiple连接最佳实践和缓存

c - Glib/Gio 异步或线程 UDP 服务器

新手Java——死锁模仿

.net - 如何在windbg中找到我的ReaderWriterLock的锁持有者(读者)

java 基于模式的格式化字符串