1
package com.sky.d_contracting_out;

import java.lang.management.ManagementFactory;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 模拟出一个死锁现场,然后用中断来处理死锁
 */
public class DeadLockDemo implements Runnable {
    
    public static ReentrantLock l1 = new ReentrantLock();
    public static ReentrantLock l2 = new ReentrantLock();
    
    private int lock;
    
    public DeadLockDemo(int lock) {
        this.lock = lock;
    }

    @Override
    public void run() {
        try {
            if(lock == 1){
                //普通的lock.lock()是不能响应中断的,lock.lockInterruptibly()能够响应中断
                l1.lockInterruptibly();
                Thread.sleep(500);
                l2.lockInterruptibly();
            } else {
                l2.lockInterruptibly();
                Thread.sleep(500);
                l1.lockInterruptibly();
            }
            
        } catch (Exception e) {
        } finally {
            if(l1.isHeldByCurrentThread()){
                l1.unlock();
            }
            if(l2.isHeldByCurrentThread()){
                l2.unlock();
            }
            System.out.println("线程退出");
        }
        
    }
    
    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(new DeadLockDemo(1));
        Thread t2 = new Thread(new DeadLockDemo(2));
        
        t1.start();
        t2.start();
        
        Thread.sleep(1000);
        
        //启动:发生死锁,线程1得到l1,线程2得到l2,然后彼此又想获得对方的锁:jps jsatck命令查看
        
        //检查死锁线程并中断
        //DeadlockChecker.check();
    }
    
    /** 检查死锁  */
    static class DeadlockChecker {
        private final static ThreadMXBean mbean = ManagementFactory.getThreadMXBean();
        
        final static Runnable deadLockChecker = new Runnable() {
            
            @Override
            public void run() {
                while(true){
                    long[] deadLockedThreadIds = mbean.findDeadlockedThreads();
                    if(deadLockedThreadIds != null){
                        ThreadInfo[] threadInfos = mbean.getThreadInfo(deadLockedThreadIds);
                        for(Thread t : Thread.getAllStackTraces().keySet()){
                            for(ThreadInfo ti : threadInfos){
                                if(ti.getThreadId() == t.getId()){
                                    t.interrupt();
                                }
                            }
                        }
                    }
                    try {
                        Thread.sleep(5000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                
            }
        };
        
        public static void check() {
            Thread t = new Thread(deadLockChecker);
            t.setDaemon(true);
            t.start();
        }
    }

}
  • jps:查看当前运行的java线程

  • jstack:查看线程栈上的信息

clipboard.png


麦冬
315 声望13 粉丝

越成熟的稻穗,越饱满厚实