private Throwable getThrowableException() {
    int h = System.identityHashCode(this);
    ExceptionNode e;
    final ReentrantLock lock = exceptionTableLock;
    lock.lock();
    try {
      expungeStaleExceptions();
      ExceptionNode[] t = exceptionTable;
      e = t[h & (t.length - 1)];
      while (e != null && e.get() != this)
        e = e.next;
    } finally {
      lock.unlock();
    }
    Throwable ex;
    if (e == null || (ex = e.ex) == null)
      return null;
    if (e.thrower != Thread.currentThread().getId()) {
      try {
        Constructor<?> noArgCtor = null;
        // public ctors only
        for (Constructor<?> c : ex.getClass().getConstructors()) {
          Class<?>[] ps = c.getParameterTypes();
          if (ps.length == 0)
            noArgCtor = c;
          else if (ps.length == 1 && ps[0] == Throwable.class)
            return (Throwable) c.newInstance(ex);
        }
        if (noArgCtor != null) {
          Throwable wx = (Throwable) noArgCtor.newInstance();
          wx.initCause(ex);
          return wx;
        }
      } catch (Exception ignore) {
      }
    }
    return ex;
  }
private Throwable getThrowableException ( ) { int h = System . identityHashCode ( this ) ; ExceptionNode e ; final ReentrantLock lock = exceptionTableLock ; lock . lock ( ) ; try { expungeStaleExceptions ( ) ; ExceptionNode [ ] t = exceptionTable ; e = t [ h & ( t . length - 1 ) ] ; while ( e != null && e . get ( ) != this ) e = e . next ; } finally { lock . unlock ( ) ; } Throwable ex ; if ( e == null || ( ex = e . ex ) == null ) return null ; if ( e . thrower != Thread . currentThread ( ) . getId ( ) ) { try { Constructor < ? > noArgCtor = null ; for ( Constructor < ? > c : ex . getClass ( ) . getConstructors ( ) ) { Class < ? > [ ] ps = c . getParameterTypes ( ) ; if ( ps . length == 0 ) noArgCtor = c ; else if ( ps . length == 1 && ps [ 0 ] == Throwable . class ) return ( Throwable ) c . newInstance ( ex ) ; } if ( noArgCtor != null ) { Throwable wx = ( Throwable ) noArgCtor . newInstance ( ) ; wx . initCause ( ex ) ; return wx ; } } catch ( Exception ignore ) { } } return ex ; }
Returns a rethrowable exception for this task, if available. To provide accurate stack traces,
if the exception was not thrown by the current thread, we try to create a new exception of the
same type as the one thrown, but with the recorded exception as its cause. If there is no such
constructor, we instead try to use a no-arg constructor, followed by initCause, to the same
effect. If none of these apply, or any fail due to other exceptions, we return the recorded
exception, which is still correct, although it may contain a misleading stack trace.

@return the exception, or null if none