8186056: Miscellaneous changes imported from jsr166 CVS 2017-09

Reviewed-by: martin, psandoz
This commit is contained in:
Doug Lea 2017-10-03 14:00:00 -07:00
parent 229cce5f44
commit c3664b7f38
16 changed files with 193 additions and 135 deletions

View file

@ -383,7 +383,7 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
*/
private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
private static final int COUNT_BITS = Integer.SIZE - 3;
private static final int CAPACITY = (1 << COUNT_BITS) - 1;
private static final int COUNT_MASK = (1 << COUNT_BITS) - 1;
// runState is stored in the high-order bits
private static final int RUNNING = -1 << COUNT_BITS;
@ -393,8 +393,8 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
private static final int TERMINATED = 3 << COUNT_BITS;
// Packing and unpacking ctl
private static int runStateOf(int c) { return c & ~CAPACITY; }
private static int workerCountOf(int c) { return c & CAPACITY; }
private static int runStateOf(int c) { return c & ~COUNT_MASK; }
private static int workerCountOf(int c) { return c & COUNT_MASK; }
private static int ctlOf(int rs, int wc) { return rs | wc; }
/*
@ -434,7 +434,7 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
* decrements are performed within getTask.
*/
private void decrementWorkerCount() {
do {} while (! compareAndDecrementWorkerCount(ctl.get()));
ctl.addAndGet(-1);
}
/**
@ -538,12 +538,17 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
* Core pool size is the minimum number of workers to keep alive
* (and not allow to time out etc) unless allowCoreThreadTimeOut
* is set, in which case the minimum is zero.
*
* Since the worker count is actually stored in COUNT_BITS bits,
* the effective limit is {@code corePoolSize & COUNT_MASK}.
*/
private volatile int corePoolSize;
/**
* Maximum pool size. Note that the actual maximum is internally
* bounded by CAPACITY.
* Maximum pool size.
*
* Since the worker count is actually stored in COUNT_BITS bits,
* the effective limit is {@code maximumPoolSize & COUNT_MASK}.
*/
private volatile int maximumPoolSize;
@ -705,7 +710,7 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
int c = ctl.get();
if (isRunning(c) ||
runStateAtLeast(c, TIDYING) ||
(runStateOf(c) == SHUTDOWN && ! workQueue.isEmpty()))
(runStateLessThan(c, STOP) && ! workQueue.isEmpty()))
return;
if (workerCountOf(c) != 0) { // Eligible to terminate
interruptIdleWorkers(ONLY_ONE);
@ -744,17 +749,12 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
* specially.
*/
private void checkShutdownAccess() {
// assert mainLock.isHeldByCurrentThread();
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkPermission(shutdownPerm);
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
for (Worker w : workers)
security.checkAccess(w.thread);
} finally {
mainLock.unlock();
}
for (Worker w : workers)
security.checkAccess(w.thread);
}
}
@ -763,14 +763,9 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
* (in which case some threads may remain uninterrupted).
*/
private void interruptWorkers() {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
for (Worker w : workers)
w.interruptIfStarted();
} finally {
mainLock.unlock();
}
// assert mainLock.isHeldByCurrentThread();
for (Worker w : workers)
w.interruptIfStarted();
}
/**
@ -896,26 +891,22 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
*/
private boolean addWorker(Runnable firstTask, boolean core) {
retry:
for (;;) {
int c = ctl.get();
int rs = runStateOf(c);
for (int c = ctl.get();;) {
// Check if queue empty only if necessary.
if (rs >= SHUTDOWN &&
! (rs == SHUTDOWN &&
firstTask == null &&
! workQueue.isEmpty()))
if (runStateAtLeast(c, SHUTDOWN)
&& (runStateAtLeast(c, STOP)
|| firstTask != null
|| workQueue.isEmpty()))
return false;
for (;;) {
int wc = workerCountOf(c);
if (wc >= CAPACITY ||
wc >= (core ? corePoolSize : maximumPoolSize))
if (workerCountOf(c)
>= ((core ? corePoolSize : maximumPoolSize) & COUNT_MASK))
return false;
if (compareAndIncrementWorkerCount(c))
break retry;
c = ctl.get(); // Re-read ctl
if (runStateOf(c) != rs)
if (runStateAtLeast(c, SHUTDOWN))
continue retry;
// else CAS failed due to workerCount change; retry inner loop
}
@ -934,10 +925,10 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
// Recheck while holding lock.
// Back out on ThreadFactory failure or if
// shut down before lock acquired.
int rs = runStateOf(ctl.get());
int c = ctl.get();
if (rs < SHUTDOWN ||
(rs == SHUTDOWN && firstTask == null)) {
if (isRunning(c) ||
(runStateLessThan(c, STOP) && firstTask == null)) {
if (t.isAlive()) // precheck that t is startable
throw new IllegalThreadStateException();
workers.add(w);
@ -1044,10 +1035,10 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
for (;;) {
int c = ctl.get();
int rs = runStateOf(c);
// Check if queue empty only if necessary.
if (rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty())) {
if (runStateAtLeast(c, SHUTDOWN)
&& (runStateAtLeast(c, STOP) || workQueue.isEmpty())) {
decrementWorkerCount();
return null;
}
@ -1140,17 +1131,12 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
wt.interrupt();
try {
beforeExecute(wt, task);
Throwable thrown = null;
try {
task.run();
} catch (RuntimeException x) {
thrown = x; throw x;
} catch (Error x) {
thrown = x; throw x;
} catch (Throwable x) {
thrown = x; throw new Error(x);
} finally {
afterExecute(task, thrown);
afterExecute(task, null);
} catch (Throwable ex) {
afterExecute(task, ex);
throw ex;
}
} finally {
task = null;
@ -1331,7 +1317,7 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
*
* If the task cannot be submitted for execution, either because this
* executor has been shutdown or because its capacity has been reached,
* the task is handled by the current {@code RejectedExecutionHandler}.
* the task is handled by the current {@link RejectedExecutionHandler}.
*
* @param command the task to execute
* @throws RejectedExecutionException at discretion of
@ -1438,7 +1424,7 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
}
public boolean isShutdown() {
return ! isRunning(ctl.get());
return runStateAtLeast(ctl.get(), SHUTDOWN);
}
/** Used by ScheduledThreadPoolExecutor. */
@ -1459,7 +1445,7 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
*/
public boolean isTerminating() {
int c = ctl.get();
return ! isRunning(c) && runStateLessThan(c, TERMINATED);
return runStateAtLeast(c, SHUTDOWN) && runStateLessThan(c, TERMINATED);
}
public boolean isTerminated() {
@ -1472,7 +1458,7 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
while (!runStateAtLeast(ctl.get(), TERMINATED)) {
while (runStateLessThan(ctl.get(), TERMINATED)) {
if (nanos <= 0L)
return false;
nanos = termination.awaitNanos(nanos);
@ -1951,7 +1937,7 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
}
int c = ctl.get();
String runState =
runStateLessThan(c, SHUTDOWN) ? "Running" :
isRunning(c) ? "Running" :
runStateAtLeast(c, TERMINATED) ? "Terminated" :
"Shutting down";
return super.toString() +