码迷,mamicode.com
首页 > 编程语言 > 详细

Java线程 - 死锁(deadlock)

时间:2014-11-20 06:46:42      阅读:144      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   io   ar   color   使用   sp   java   

一、死锁

死锁是指这样一种状况。当多个线程竞争稀缺资源的时,由于他们相互等待获取对方线程所拥有的资源,大家都无法满足,从而都无法继续执行的情形。

 bubuko.com,布布扣

P2进程拥有R1资源,但他正请求获取R2资源;而P1进程拥有R2资源,但他正请求R1资源。

 

1.1 Coffman条件--产生死锁的4个条件

如果一个系统中如下4种情形同时存在,则产生死锁情形的机会就会上升

  • 互斥条件:进程要求对所分配的资源进行排它性控制,即在一段时间内某资源仅为一进程所占用
  • 等待和保持条件:当进程因请求资源而阻塞时,对已获得的资源保持不放
  • 不可剥夺条件进程已获得的资源在未使用完之前,不能剥夺,只能在使用完时由自己释放
  • 环路等待条件:在发生死锁时,必然存在一个进程--资源的环形链。更一般性来讲会有进程集合{P1,P2,P3....Pn},P1 申请P2获取的资源,P2申请P3资源....而Pn申请P1获取的资源,这样形成了一个闭环。

这4个条件即Coffman条件,由Edward G.Coffman, Jr先生于1971年首次提出。

 

二、java多线程死锁探测

从JDK1.5开始java.lang.management包提供了ThreadMXBean类,该类可用获取关于线程的各种各样的信息,包括探测线程的死锁。findMonitorDeadlockedThreads()方法返回long[],这些long[]表示发生死锁的线程的id。如果long[]数组等于null则表示没有发现死锁的线程。但这个方法只是监控object monitor的死锁,对于使用java.util.concurrent包的ownable synchronizer则无能为力。为此JDK1.6引入了一个新的方法findDeadlockedThreads()除了监控object monitor死锁外,同时还监控ownable synchronizer的死锁。

通过建立一个定期任务,让它使用ThreadMXBean定期核查是否存在死锁的线程,就可以解决线程死锁探测的问题。例如:

public class ThreadDeadlockDetector {
    
    //建立定期任务的调度器
    private final Timer threadCheck = new Timer("ThreadDeadLockDector",true);
    
    private final Collection<Listener> listeners = new CopyOnWriteArraySet<Listener>();
    
    private final ThreadMXBean mbean = ManagementFactory.getThreadMXBean();    
    
    private static final int DEFAULT_DEADLOCK_CHECK_PERIOD = 10000;
    
    public ThreadDeadlockDetector(){
        this(DEFAULT_DEADLOCK_CHECK_PERIOD);
    }
    
    public ThreadDeadlockDetector(int deadlockCheckPeriod){
        //建立一个定期核查的任务
        threadCheck.schedule(new TimerTask(){
            @Override
            public void run() {
                checkForDeadlocks();
            }
            
        }, 10, deadlockCheckPeriod);
    }
    
    //一旦返现有死锁,就发出死锁报警
    private void checkForDeadlocks() {
        long[] ids = findDeadlockedThreads();
        if(ids != null && ids.length > 0) {
            Thread[] threads = new Thread[ids.length];
            for(int i=0; i<threads.length; i++){
                threads[i] = findMatchingThread(mbean.getThreadInfo(ids[i]));
            }
            fireDeadlockDetected(threads);
        }
        
    }
    
    //核查是否存在死锁
    private long[] findDeadlockedThreads(){
        if(mbean.isSynchronizerUsageSupported()){
            return mbean.findDeadlockedThreads();
        }else{
            return mbean.findMonitorDeadlockedThreads();
        }
    }
    
    private Thread findMatchingThread(ThreadInfo inf){
        for(Thread thread:Thread.getAllStackTraces().keySet()){
            if(thread.getId() == inf.getThreadId()){
                return thread;
            }
        }
        
        throw new IllegalStateException("Deadlocked Thread not found");

    }
    
    public boolean addListener(Listener l){
        return listeners.add(l);
    }
    
    public boolean removeListener(Listener l){
        return listeners.remove(l);
    }
    
    private void fireDeadlockDetected(Thread[] threads){
        for(Listener l : listeners){
            l.deallockDetected(threads);
        }
    }
    
    public interface Listener {
        void deallockDetected(Thread[] deadlockedThreads);
    }
}

 

Java线程 - 死锁(deadlock)

标签:style   blog   http   io   ar   color   使用   sp   java   

原文地址:http://www.cnblogs.com/thomaschen750215/p/4109646.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!