- 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
- }
- }
- }
这个死锁检测算法位于DefaultIoFuture中,策略是分两步进行,首先是用一个简单而快速的方法检测,然后再用一个更精确地方法来检测。 第一个方法通过getStackTrace获得当前的线程的整个堆栈的元素数组,然后遍历这个数组,看是否有某一层的调用的class是AbstractPollingIoProcessor,如果有,就是存在循环调用,出现死锁。这是因为AbstractPollingIoProcessor是实现IoProcessor的抽象类,包含一个Executor,创建线程处理任务,