src/java.base/share/classes/java/util/concurrent/FutureTask.java

Print this page

        

*** 161,181 **** return state != NEW; } public boolean cancel(boolean mayInterruptIfRunning) { if (!(state == NEW && ! UNSAFE.compareAndSwapInt(this, stateOffset, NEW, mayInterruptIfRunning ? INTERRUPTING : CANCELLED))) return false; try { // in case call to interrupt throws exception if (mayInterruptIfRunning) { try { Thread t = runner; if (t != null) t.interrupt(); } finally { // final state ! UNSAFE.putOrderedInt(this, stateOffset, INTERRUPTED); } } } finally { finishCompletion(); } --- 161,181 ---- return state != NEW; } public boolean cancel(boolean mayInterruptIfRunning) { if (!(state == NEW && ! U.compareAndSwapInt(this, STATE, NEW, mayInterruptIfRunning ? INTERRUPTING : CANCELLED))) return false; try { // in case call to interrupt throws exception if (mayInterruptIfRunning) { try { Thread t = runner; if (t != null) t.interrupt(); } finally { // final state ! U.putOrderedInt(this, STATE, INTERRUPTED); } } } finally { finishCompletion(); }
*** 225,237 **** * upon successful completion of the computation. * * @param v the value */ protected void set(V v) { ! if (UNSAFE.compareAndSwapInt(this, stateOffset, NEW, COMPLETING)) { outcome = v; ! UNSAFE.putOrderedInt(this, stateOffset, NORMAL); // final state finishCompletion(); } } /** --- 225,237 ---- * upon successful completion of the computation. * * @param v the value */ protected void set(V v) { ! if (U.compareAndSwapInt(this, STATE, NEW, COMPLETING)) { outcome = v; ! U.putOrderedInt(this, STATE, NORMAL); // final state finishCompletion(); } } /**
*** 243,263 **** * upon failure of the computation. * * @param t the cause of failure */ protected void setException(Throwable t) { ! if (UNSAFE.compareAndSwapInt(this, stateOffset, NEW, COMPLETING)) { outcome = t; ! UNSAFE.putOrderedInt(this, stateOffset, EXCEPTIONAL); // final state finishCompletion(); } } public void run() { if (state != NEW || ! !UNSAFE.compareAndSwapObject(this, runnerOffset, ! null, Thread.currentThread())) return; try { Callable<V> c = callable; if (c != null && state == NEW) { V result; --- 243,262 ---- * upon failure of the computation. * * @param t the cause of failure */ protected void setException(Throwable t) { ! if (U.compareAndSwapInt(this, STATE, NEW, COMPLETING)) { outcome = t; ! U.putOrderedInt(this, STATE, EXCEPTIONAL); // final state finishCompletion(); } } public void run() { if (state != NEW || ! !U.compareAndSwapObject(this, RUNNER, null, Thread.currentThread())) return; try { Callable<V> c = callable; if (c != null && state == NEW) { V result;
*** 294,305 **** * * @return {@code true} if successfully run and reset */ protected boolean runAndReset() { if (state != NEW || ! !UNSAFE.compareAndSwapObject(this, runnerOffset, ! null, Thread.currentThread())) return false; boolean ran = false; int s = state; try { Callable<V> c = callable; --- 293,303 ---- * * @return {@code true} if successfully run and reset */ protected boolean runAndReset() { if (state != NEW || ! !U.compareAndSwapObject(this, RUNNER, null, Thread.currentThread())) return false; boolean ran = false; int s = state; try { Callable<V> c = callable;
*** 362,372 **** * nulls out callable. */ private void finishCompletion() { // assert state > COMPLETING; for (WaitNode q; (q = waiters) != null;) { ! if (UNSAFE.compareAndSwapObject(this, waitersOffset, q, null)) { for (;;) { Thread t = q.thread; if (t != null) { q.thread = null; LockSupport.unpark(t); --- 360,370 ---- * nulls out callable. */ private void finishCompletion() { // assert state > COMPLETING; for (WaitNode q; (q = waiters) != null;) { ! if (U.compareAndSwapObject(this, WAITERS, q, null)) { for (;;) { Thread t = q.thread; if (t != null) { q.thread = null; LockSupport.unpark(t);
*** 389,403 **** /** * Awaits completion or aborts on interrupt or timeout. * * @param timed true if use timed waits * @param nanos time to wait, if timed ! * @return state upon completion */ private int awaitDone(boolean timed, long nanos) throws InterruptedException { ! final long deadline = timed ? System.nanoTime() + nanos : 0L; WaitNode q = null; boolean queued = false; for (;;) { if (Thread.interrupted()) { removeWaiter(q); --- 387,408 ---- /** * Awaits completion or aborts on interrupt or timeout. * * @param timed true if use timed waits * @param nanos time to wait, if timed ! * @return state upon completion or at timeout */ private int awaitDone(boolean timed, long nanos) throws InterruptedException { ! // The code below is very delicate, to achieve these goals: ! // - call nanoTime exactly once for each call to park ! // - if nanos <= 0, return promptly without allocation or nanoTime ! // - if nanos == Long.MIN_VALUE, don't underflow ! // - if nanos == Long.MAX_VALUE, and nanoTime is non-monotonic ! // and we suffer a spurious wakeup, we will do no worse than ! // to park-spin for a while ! long startTime = 0L; // Special value 0L means not yet parked WaitNode q = null; boolean queued = false; for (;;) { if (Thread.interrupted()) { removeWaiter(q);
*** 410,431 **** q.thread = null; return s; } else if (s == COMPLETING) // cannot time out yet Thread.yield(); ! else if (q == null) q = new WaitNode(); else if (!queued) ! queued = UNSAFE.compareAndSwapObject(this, waitersOffset, q.next = waiters, q); else if (timed) { ! nanos = deadline - System.nanoTime(); ! if (nanos <= 0L) { removeWaiter(q); return state; } ! LockSupport.parkNanos(this, nanos); } else LockSupport.park(this); } } --- 415,448 ---- q.thread = null; return s; } else if (s == COMPLETING) // cannot time out yet Thread.yield(); ! else if (q == null) { ! if (timed && nanos <= 0L) ! return s; q = new WaitNode(); + } else if (!queued) ! queued = U.compareAndSwapObject(this, WAITERS, q.next = waiters, q); else if (timed) { ! final long parkNanos; ! if (startTime == 0L) { // first time ! startTime = System.nanoTime(); ! if (startTime == 0L) ! startTime = 1L; ! parkNanos = nanos; ! } else { ! long elapsed = System.nanoTime() - startTime; ! if (elapsed >= nanos) { removeWaiter(q); return state; } ! parkNanos = nanos - elapsed; ! } ! LockSupport.parkNanos(this, parkNanos); } else LockSupport.park(this); } }
*** 452,485 **** else if (pred != null) { pred.next = s; if (pred.thread == null) // check for race continue retry; } ! else if (!UNSAFE.compareAndSwapObject(this, waitersOffset, ! q, s)) continue retry; } break; } } } // Unsafe mechanics ! private static final sun.misc.Unsafe UNSAFE; ! private static final long stateOffset; ! private static final long runnerOffset; ! private static final long waitersOffset; static { try { ! UNSAFE = sun.misc.Unsafe.getUnsafe(); Class<?> k = FutureTask.class; ! stateOffset = UNSAFE.objectFieldOffset ! (k.getDeclaredField("state")); ! runnerOffset = UNSAFE.objectFieldOffset ! (k.getDeclaredField("runner")); ! waitersOffset = UNSAFE.objectFieldOffset ! (k.getDeclaredField("waiters")); } catch (Exception e) { throw new Error(e); } } --- 469,498 ---- else if (pred != null) { pred.next = s; if (pred.thread == null) // check for race continue retry; } ! else if (!U.compareAndSwapObject(this, WAITERS, q, s)) continue retry; } break; } } } // Unsafe mechanics ! private static final sun.misc.Unsafe U; ! private static final long STATE; ! private static final long RUNNER; ! private static final long WAITERS; static { try { ! U = sun.misc.Unsafe.getUnsafe(); Class<?> k = FutureTask.class; ! STATE = U.objectFieldOffset(k.getDeclaredField("state")); ! RUNNER = U.objectFieldOffset(k.getDeclaredField("runner")); ! WAITERS = U.objectFieldOffset(k.getDeclaredField("waiters")); } catch (Exception e) { throw new Error(e); } }