• 通过编程发现Java死锁


    通过stack也可以发现死锁。

    测试类

    import java.util.concurrent.TimeUnit;
    
    public class Test {
        public static void main(String[] args) {
            DeadlockDetector deadlockDetector = new DeadlockDetector(new DeadlockConsoleHandler(), 5, TimeUnit.SECONDS);
            deadlockDetector.start();
    
            final Object lock1 = new Object();
            final Object lock2 = new Object();
            Thread thread1 = new Thread(()->{
                synchronized (lock1) {
                    System.out.println("Thread1 acquired lock1");
                    try {
                        TimeUnit.MILLISECONDS.sleep(500);
                    } catch (InterruptedException ignore) {
                    }
                    synchronized (lock2) {
                        System.out.println("Thread1 acquired lock2");
                    }
                }
            });
            thread1.start();
            Thread thread2 = new Thread(()->{
                synchronized (lock2) {
                    System.out.println("Thread2 acquired lock2");
                    synchronized (lock1) {
                        System.out.println("Thread2 acquired lock1");
                    }
                }
            });
            thread2.start();
        }
    }

    处理类

    public class DeadlockConsoleHandler implements DeadlockHandler {
        @Override
        public void handleDeadlock(final ThreadInfo[] deadlockedThreads) {
            if (deadlockedThreads != null) {
                System.err.println("Deadlock detected!");
                Map<Thread, StackTraceElement[]> stackTraceMap = Thread.getAllStackTraces();
                for (ThreadInfo threadInfo : deadlockedThreads) {
                    if (threadInfo != null) {
                        for (Thread thread : Thread.getAllStackTraces().keySet()) {
                            if (thread.getId() == threadInfo.getThreadId()) {
                                System.err.println(threadInfo.toString().trim());
                                for (StackTraceElement ste : thread.getStackTrace()) {
                                    System.err.println("t" + ste.toString().trim());
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    import java.lang.management.ThreadInfo;
    public interface DeadlockHandler {
        void handleDeadlock(final ThreadInfo[] deadlockedThreads);
    }

    关键类

    import java.lang.management.ManagementFactory;
    import java.lang.management.ThreadInfo;
    import java.lang.management.ThreadMXBean;
    import java.util.concurrent.Executors;
    import java.util.concurrent.ScheduledExecutorService;
    import java.util.concurrent.TimeUnit;
    
    public class DeadlockDetector {
    
        private final DeadlockHandler deadlockHandler;
        private final long period;
        private final TimeUnit unit;
        private final ThreadMXBean mbean = ManagementFactory.getThreadMXBean();
        private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
    
        final Runnable deadlockCheck = new Runnable() {
            @Override
            public void run() {
                long[] deadlockedThreadIds = mbean.findDeadlockedThreads();
                if (deadlockedThreadIds != null) {
                    ThreadInfo[] threadInfos = mbean.getThreadInfo(deadlockedThreadIds);
                    deadlockHandler.handleDeadlock(threadInfos);
                }
            }
        };
    
        public DeadlockDetector(final DeadlockHandler deadlockHandler, final long period, final TimeUnit unit) {
            this.deadlockHandler = deadlockHandler;
            this.period = period;
            this.unit = unit;
        }
    
        public void start() {
            this.scheduler.scheduleAtFixedRate(this.deadlockCheck, this.period, this.period, this.unit);
        }
    }

    测试结果

    Thread1 acquired lock1
    Thread2 acquired lock2
    Deadlock detected!
    "Thread-1" Id=12 BLOCKED on java.lang.Object@6a80bb83 owned by "Thread-0" Id=11
    ttest.Test.lambda$main$1(Test.java:32)
    ttest.Test$$Lambda$2/363771819.run(Unknown Source)
    tjava.lang.Thread.run(Thread.java:745)
    "Thread-0" Id=11 BLOCKED on java.lang.Object@6ebf220b owned by "Thread-1" Id=12
    ttest.Test.lambda$main$0(Test.java:23)
    ttest.Test$$Lambda$1/668386784.run(Unknown Source)
    tjava.lang.Thread.run(Thread.java:745)
    Deadlock detected!
  • 相关阅读:
    SQL Server 数据库定时自动备份
    SQL SERVER 2012设置自动备份数据库
    SyncNavigator 数据库同步软件怎么用?
    SyncNavigator下载|SyncNavigator数据库同步软件 v8.4.1
    关于数据同步的几种实现
    课堂练习-找水王:
    软件工程第十四周总结
    Alpha版(内部测试版)发布
    软件工程第十三周总结
    意见评论汇总
  • 原文地址:https://www.cnblogs.com/wade-luffy/p/6101128.html
Copyright © 2020-2023  润新知