mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 15:24:43 +02:00
8186056: Miscellaneous changes imported from jsr166 CVS 2017-09
Reviewed-by: martin, psandoz
This commit is contained in:
parent
229cce5f44
commit
c3664b7f38
16 changed files with 193 additions and 135 deletions
|
@ -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() +
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue