Package xbird.util.concurrent

Source Code of xbird.util.concurrent.ThreadDeadlockDetector$Listener

/*
* @(#)$Id$
*
* Copyright 2006-2008 Makoto YUI
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Contributors:
*     Makoto YUI - initial implementation
*/
package xbird.util.concurrent;

import java.lang.management.ManagementFactory;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;
import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.atomic.AtomicBoolean;

/**
*
* <DIV lang="en"></DIV>
* <DIV lang="ja"></DIV>
*
* @author Makoto YUI (yuin405+xbird@gmail.com)
* @link http://www.javaspecialists.co.za/archive/newsletter.do?issue=130
* @since 1.6
*/
public final class ThreadDeadlockDetector {

    private final Timer threadCheck = new Timer("ThreadDeadlockDetector", true);
    private final ThreadMXBean mbean;
    private final boolean isObjectMonitorUsageSupported;
    private final boolean isSynchronizerUsageSupported;
    private final long deadlockCheckPeriod;

    private final Set<Listener> listeners = new CopyOnWriteArraySet<Listener>();
    private final AtomicBoolean started = new AtomicBoolean(false);

    /**
     * The number of milliseconds between checking for deadlocks.
     * It may be expensive to check for deadlocks, and it is not
     * critical to know so quickly.
     */
    private static final long DEFAULT_DEADLOCK_CHECK_PERIOD = 10000L;

    public ThreadDeadlockDetector() {
        this(DEFAULT_DEADLOCK_CHECK_PERIOD);
    }

    public ThreadDeadlockDetector(long deadlockCheckPeriod) {
        this.mbean = ManagementFactory.getThreadMXBean();
        this.isObjectMonitorUsageSupported = mbean.isObjectMonitorUsageSupported();
        this.isSynchronizerUsageSupported = mbean.isSynchronizerUsageSupported();
        this.deadlockCheckPeriod = deadlockCheckPeriod;
    }

    public void start() {
        if(started.compareAndSet(false, true)) {
            threadCheck.schedule(new TimerTask() {
                public void run() {
                    checkForDeadlocks();
                }
            }, 10, deadlockCheckPeriod);
        }
    }

    public void stop() {
        threadCheck.cancel();
    }

    private void checkForDeadlocks() {
        long[] ids = findDeadlockedThreads();
        if(ids != null && ids.length > 0) {
            ThreadInfo[] infos = mbean.getThreadInfo(ids, isObjectMonitorUsageSupported, isSynchronizerUsageSupported);
            fireDeadlockDetected(infos);
        }
    }

    private long[] findDeadlockedThreads() {
        // JDK 1.5 only supports the findMonitorDeadlockedThreads()
        // method, so you need to comment out the following three lines
        if(isSynchronizerUsageSupported) {
            return mbean.findDeadlockedThreads();
        } else {
            return mbean.findMonitorDeadlockedThreads();
        }
    }

    private void fireDeadlockDetected(ThreadInfo[] threadInfos) {
        for(Listener l : listeners) {
            l.deadlockDetected(threadInfos);
        }
    }

    public boolean addListener(Listener l) {
        return listeners.add(l);
    }

    public boolean removeListener(Listener l) {
        return listeners.remove(l);
    }

    /**
     * This is called whenever a problem with threads is detected.
     */
    public interface Listener {
        void deadlockDetected(ThreadInfo[] deadlockedThreads);
    }

    public static final class StderrDeadlockReporter implements ThreadDeadlockDetector.Listener {
        public void deadlockDetected(ThreadInfo[] threads) {
            System.err.println("Deadlocked Threads:");
            System.err.println("-------------------");
            for(ThreadInfo ti : threads) {
                System.err.println(ti);
            }
        }
    }
}
TOP

Related Classes of xbird.util.concurrent.ThreadDeadlockDetector$Listener

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.