public T get(long timeout, TimeUnit unit) { if (isDone()) { return getResultValue(); } Thread thread = Thread.currentThread(); // _thread = thread; long expires = unit.toMillis(timeout) + System.currentTimeMillis(); while (true) { if (isDone()) { return getResultValue(); } else if (_state == FutureState.ASYNC) { Result<Object> chain = _chain; Object chainValue = _chainValue; _chain = null; _chainValue = null; _state = FutureState.INIT; // _thread = null; chain.completeFuture(chainValue); /* if (isDone()) { return getResultValue(); } */ // _thread = thread; } else { if (ServiceRef.flushOutboxAndExecuteLast()) { // if pending messages, continue to process them continue; } // ServiceRef.flushOutbox(); _thread = thread; if (_state.isParkRequired()) { if (expires < System.currentTimeMillis()) { _thread = null; throw new ServiceExceptionFutureTimeout("future timeout " + timeout + " " + unit); } LockSupport.parkUntil(expires); } _thread = null; } } }
@Override public final void run() { String oldName = null; try { _thread = Thread.currentThread(); _thread.setContextClassLoader(_classLoader); oldName = _thread.getName(); _thread.setName(getThreadName()); onThreadStart(); long now = getCurrentTimeActual(); long expires = now + _workerIdleTimeout; do { while (_taskState.getAndSet(TASK_SLEEP) == TASK_READY) { _thread.setContextClassLoader(_classLoader); long delta = runTask(); now = getCurrentTimeActual(); if (delta < 0) { expires = now + _workerIdleTimeout; } else { expires = now + delta; } } if (isClosed()) return; if (_taskState.compareAndSet(TASK_SLEEP, TASK_PARK)) { Thread.interrupted(); LockSupport.parkUntil(expires); if (isPermanent()) _taskState.set(TASK_READY); } } while (_taskState.get() == TASK_READY || isPermanent() || getCurrentTimeActual() < expires); } catch (Throwable e) { WarningService.sendCurrentWarning(this, e); log.log(Level.WARNING, e.toString(), e); } finally { Thread thread = _thread; _thread = null; _isActive.set(false); if (_taskState.get() == TASK_READY) wake(); onThreadComplete(); if (thread != null && oldName != null) thread.setName(oldName); } }
final void park(long expires) { Thread thread = _thread; while (_thread != null && Alarm.getCurrentTimeActual() < expires) { try { Thread.interrupted(); LockSupport.parkUntil(thread, expires); } catch (Exception e) { } } /* if (_thread != null) { System.out.println("TIMEOUT:" + thread); Thread.dumpStack(); } */ _thread = null; }