// 方法throw折行空4个空格 private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException { s.defaultWriteObject(); s.writeObject(getException()); }
// (ForkJoinTask.class.getDeclaredField("status"))参数折行 static { exceptionTableLock = new ReentrantLock(); exceptionTableRefQueue = new ReferenceQueue<Object>(); exceptionTable = new ExceptionNode[EXCEPTION_MAP_CAPACITY]; try { UNSAFE = sun.misc.Unsafe.getUnsafe(); statusOffset = UNSAFE.objectFieldOffset (ForkJoinTask.class.getDeclaredField("status")); } catch (Exception e) { throw new Error(e); } }
/** * Wakes up or creates a worker. */ final void signalWork() { /* * The while condition is true if: (there is are too few total * workers OR there is at least one waiter) AND (there are too * few active workers OR the pool is terminating). The value * of e distinguishes the remaining cases: zero (no waiters) * for create, negative if terminating (in which case do * nothing), else release a waiter. The secondary checks for * release (non-null array etc) can fail if the pool begins * terminating after the test, and don't impose any added cost * because JVMs must perform null and bounds checks anyway. */ long c; int e, u; while ((((e = (int)(c = ctl)) | (u = (int)(c >>> 32))) & (INT_SIGN|SHORT_SIGN)) == (INT_SIGN|SHORT_SIGN) && e >= 0) { if (e > 0) { // release a waiting worker int i; ForkJoinWorkerThread w; ForkJoinWorkerThread[] ws; if ((ws = workers) == null || (i = ~e & SMASK) >= ws.length || (w = ws[i]) == null) break; long nc = (((long)(w.nextWait & E_MASK)) | ((long)(u + UAC_UNIT) << 32)); if (w.eventCount == e && UNSAFE.compareAndSwapLong(this, ctlOffset, c, nc)) { w.eventCount = (e + EC_UNIT) & E_MASK; if (w.parked) UNSAFE.unpark(w); break; } } else if (UNSAFE.compareAndSwapLong (this, ctlOffset, c, (long)(((u + UTC_UNIT) & UTC_MASK) | ((u + UAC_UNIT) & UAC_MASK)) << 32)) { addWorker(); break; } } }
private boolean tryReleaseWaiter() { long c; int e, i; ForkJoinWorkerThread w; ForkJoinWorkerThread[] ws; if ((e = (int)(c = ctl)) > 0 && (int)(c >> AC_SHIFT) < 0 && (ws = workers) != null && (i = ~e & SMASK) < ws.length && (w = ws[i]) != null) { long nc = ((long)(w.nextWait & E_MASK) | ((c + AC_UNIT) & (AC_MASK|TC_MASK))); if (w.eventCount != e || !UNSAFE.compareAndSwapLong(this, ctlOffset, c, nc)) return false; w.eventCount = (e + EC_UNIT) & E_MASK; if (w.parked) UNSAFE.unpark(w); } return true; }
final int idlePerActive() { // Approximate at powers of two for small values, saturate past 4 int p = parallelism; int a = p + (int)(ctl >> AC_SHIFT); return (a > (p >>>= 1) ? 0 : a > (p >>>= 1) ? 1 : a > (p >>>= 1) ? 2 : a > (p >>>= 1) ? 4 : 8); }
/** * Final callback from terminating worker. Removes record of * worker from array, and adjusts counts. If pool is shutting * down, tries to complete termination. * * @param w the worker */ final void deregisterWorker(ForkJoinWorkerThread w, Throwable ex) { int idx = w.poolIndex; int sc = w.stealCount; int steps = 0; // Remove from array, adjust worker counts and collect steal count. // We can intermix failed removes or adjusts with steal updates do { long s, c; int g; if (steps == 0 && ((g = scanGuard) & SG_UNIT) == 0 && UNSAFE.compareAndSwapInt(this, scanGuardOffset, g, g |= SG_UNIT)) { ForkJoinWorkerThread[] ws = workers; if (ws != null && idx >= 0 && idx < ws.length && ws[idx] == w) ws[idx] = null; // verify nextWorkerIndex = idx; scanGuard = g + SG_UNIT; steps = 1; } if (steps == 1 && UNSAFE.compareAndSwapLong(this, ctlOffset, c = ctl, (((c - AC_UNIT) & AC_MASK) | ((c - TC_UNIT) & TC_MASK) | (c & ~(AC_MASK|TC_MASK))))) steps = 2; if (sc != 0 && UNSAFE.compareAndSwapLong(this, stealCountOffset, s = stealCount, s + sc)) sc = 0; } while (steps != 2 || sc != 0); if (!tryTerminate(false)) { if (ex != null) // possibly replace if died abnormally signalWork(); else tryReleaseWaiter(); } }
public final Throwable getException() { int s = status; return ((s >= NORMAL) ? null : (s == CANCELLED) ? new CancellationException() : getThrowableException()); }
public static ForkJoinPool getPool() { Thread t = Thread.currentThread(); return (t instanceof ForkJoinWorkerThread) ? ((ForkJoinWorkerThread) t).pool : null; }
public boolean tryUnfork() { return ((ForkJoinWorkerThread) Thread.currentThread()) .unpushTask(this); }
public static ExecutorService newSingleThreadExecutor() { return new FinalizableDelegatedExecutorService (new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>())); }
private static final long SHRINK_RATE = 4L * 1000L * 1000L * 1000L; // 4 seconds
boolean casNext(SNode cmp, SNode val) { return cmp == next && UNSAFE.compareAndSwapObject(this, nextOffset, cmp, val); }