首先我们看看mina里面死锁的检测方法:
// private void checkDeadLock() {
// // Only read / write / connect / write future can cause dead lock.
// if (!(this instanceof CloseFuture || this instanceof WriteFuture ||
// this instanceof ReadFuture || this instanceof ConnectFuture)) {
// return;
// }
//
// // Get the current thread stackTrace.
// // Using Thread.currentThread().getStackTrace() is the best solution,
// // even if slightly less efficient than doing a new Exception().getStackTrace(),
// // as internally, it does exactly the same thing. The advantage of using
// // this solution is that we may benefit some improvement with some
// // future versions of Java.
// StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
//
// // Simple and quick check.
// for (StackTraceElement s: stackTrace) {
// if (AbstractPollingIoProcessor.class.getName().equals(s.getClassName())) {
// IllegalStateException e = new IllegalStateException( "t" );
// e.getStackTrace();
// throw new IllegalStateException(
// "DEAD LOCK: " + IoFuture.class.getSimpleName() +
// ".await() was invoked from an I/O processor thread. " +
// "Please use " + IoFutureListener.class.getSimpleName() +
// " or configure a proper thread model alternatively.");
// }
// }
//
// // And then more precisely.
// for (StackTraceElement s: stackTrace) {
// try {
// Class<?> cls = DefaultIoFuture.class.getClassLoader().loadClass(s.getClassName());
// if (IoProcessor.class.isAssignableFrom(cls)) {
// throw new IllegalStateException(
// "DEAD LOCK: " + IoFuture.class.getSimpleName() +
// ".await() was invoked from an I/O processor thread. " +
// "Please use " + IoFutureListener.class.getSimpleName() +
// " or configure a proper thread model alternatively.");
// }
// } catch (Exception cnfe) {
// // Ignore
// }
// }
// }
}
同理:
DeadlockHandler接口
package handler;
import java.lang.management.ThreadInfo;
public interface DeadlockHandler {
public void handleDeadlock(final ThreadInfo[] deadlockedThreads);
}
DeadlockConsoleHandler 实现 DeadlockHandler接口
package handler;
import java.lang.management.ThreadInfo;
public class DeadlockConsoleHandler implements DeadlockHandler {
@Override
public void handleDeadlock(ThreadInfo[] deadlockedThreads) {
if (deadlockedThreads != null) {
System.err.println("Deadlock detected!");
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());
}
}
}
}
}
}
}
}
死锁检测类:DeadlockDetector
package detector;
import handler.DeadlockHandler;
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 timeUnit;
private final ThreadMXBean mBean = ManagementFactory.getThreadMXBean();
private final ScheduledExecutorService scheduler =
Executors.newScheduledThreadPool(1);
public DeadlockDetector(final DeadlockHandler deadlockHandler, final long period, final TimeUnit timeUnit) {
this.deadlockHandler = deadlockHandler;
this.period = period;
this.timeUnit = timeUnit;
}
final Runnable deadlockCheck = new Runnable () {
@Override
public void run() {
long[] deadlockedThreadIds = DeadlockDetector.this.mBean.findDeadlockedThreads();
if (deadlockedThreadIds != null) {
ThreadInfo[] threadInfos = DeadlockDetector.this.mBean.getThreadInfo(deadlockedThreadIds);
DeadlockDetector.this.deadlockHandler.handleDeadlock(threadInfos);
}
}
};
public void start() {
this.scheduler.scheduleAtFixedRate(this.deadlockCheck, this.period, this.period, this.timeUnit);
}
}
Main 类:
package main;
import handler.DeadlockConsoleHandler;
import java.util.concurrent.TimeUnit;
import detector.DeadlockDetector;
public class Main {
public static void main(String[] args) {
DeadlockDetector deadlockDetector = new DeadlockDetector(new DeadlockConsoleHandler(), 5, TimeUnit.SECONDS);
deadlockDetector.start();
runThread();
}
public static void runThread() {
final Object lock1 = new Object();
final Object lock2 = new Object();
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
synchronized (lock1) {
System.out.println("Thread1 acquired lock1");
try {
TimeUnit.MICROSECONDS.sleep(1000);
} catch (InterruptedException e) {
}
synchronized (lock2) {
System.out.println("Thread2 acquired lock2");
}
}
}
});
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
synchronized (lock2) {
System.out.println("Thread2 acquired lock2");
try {
TimeUnit.MICROSECONDS.sleep(1000);
} catch (InterruptedException e) {
}
synchronized (lock1) {
System.out.println("Thread2 acquired lock1");
}
}
}
});
thread1.start();
thread2.start();
System.out.println(thread1.getStackTrace());
}
}