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

@ -211,7 +211,7 @@ public class ArrayDeque<E> extends AbstractCollection<E>
}
/**
* Increments i, mod modulus.
* Circularly increments i, mod modulus.
* Precondition and postcondition: 0 <= i < modulus.
*/
static final int inc(int i, int modulus) {
@ -220,7 +220,7 @@ public class ArrayDeque<E> extends AbstractCollection<E>
}
/**
* Decrements i, mod modulus.
* Circularly decrements i, mod modulus.
* Precondition and postcondition: 0 <= i < modulus.
*/
static final int dec(int i, int modulus) {
@ -233,7 +233,7 @@ public class ArrayDeque<E> extends AbstractCollection<E>
* Precondition: 0 <= i < modulus, 0 <= distance <= modulus.
* @return index 0 <= i < modulus
*/
static final int add(int i, int distance, int modulus) {
static final int inc(int i, int distance, int modulus) {
if ((i += distance) - modulus >= 0) i -= modulus;
return i;
}
@ -825,7 +825,7 @@ public class ArrayDeque<E> extends AbstractCollection<E>
final int i, n;
return ((n = sub(getFence(), i = cursor, es.length) >> 1) <= 0)
? null
: new DeqSpliterator(i, cursor = add(i, n, es.length));
: new DeqSpliterator(i, cursor = inc(i, n, es.length));
}
public void forEachRemaining(Consumer<? super E> action) {

View file

@ -1394,8 +1394,8 @@ public class ConcurrentHashMap<K,V> extends AbstractMap<K,V>
}
/**
* Saves the state of the {@code ConcurrentHashMap} instance to a
* stream (i.e., serializes it).
* Saves this map to a stream (that is, serializes it).
*
* @param s the stream
* @throws java.io.IOException if an I/O error occurs
* @serialData
@ -1439,7 +1439,7 @@ public class ConcurrentHashMap<K,V> extends AbstractMap<K,V>
}
/**
* Reconstitutes the instance from a stream (that is, deserializes it).
* Reconstitutes this map from a stream (that is, deserializes it).
* @param s the stream
* @throws ClassNotFoundException if the class of a serialized object
* could not be found

View file

@ -174,6 +174,10 @@ public class ExecutorCompletionService<V> implements CompletionService<V> {
this.completionQueue = completionQueue;
}
/**
* @throws RejectedExecutionException {@inheritDoc}
* @throws NullPointerException {@inheritDoc}
*/
public Future<V> submit(Callable<V> task) {
if (task == null) throw new NullPointerException();
RunnableFuture<V> f = newTaskFor(task);
@ -181,6 +185,10 @@ public class ExecutorCompletionService<V> implements CompletionService<V> {
return f;
}
/**
* @throws RejectedExecutionException {@inheritDoc}
* @throws NullPointerException {@inheritDoc}
*/
public Future<V> submit(Runnable task, V result) {
if (task == null) throw new NullPointerException();
RunnableFuture<V> f = newTaskFor(task, result);

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() +

View file

@ -342,11 +342,13 @@ public enum TimeUnit {
* using:
*
* <pre> {@code
* public synchronized Object poll(long timeout, TimeUnit unit)
* public E poll(long timeout, TimeUnit unit)
* throws InterruptedException {
* while (empty) {
* unit.timedWait(this, timeout);
* ...
* synchronized (lock) {
* while (isEmpty()) {
* unit.timedWait(lock, timeout);
* ...
* }
* }
* }}</pre>
*

View file

@ -73,7 +73,7 @@ import java.util.concurrent.TimeUnit;
* available in the buffer. This can be achieved using two
* {@link Condition} instances.
* <pre>
* class BoundedBuffer {
* class BoundedBuffer&lt;E&gt; {
* <b>final Lock lock = new ReentrantLock();</b>
* final Condition notFull = <b>lock.newCondition(); </b>
* final Condition notEmpty = <b>lock.newCondition(); </b>
@ -81,7 +81,7 @@ import java.util.concurrent.TimeUnit;
* final Object[] items = new Object[100];
* int putptr, takeptr, count;
*
* public void put(Object x) throws InterruptedException {
* public void put(E x) throws InterruptedException {
* <b>lock.lock();
* try {</b>
* while (count == items.length)
@ -95,12 +95,12 @@ import java.util.concurrent.TimeUnit;
* }</b>
* }
*
* public Object take() throws InterruptedException {
* public E take() throws InterruptedException {
* <b>lock.lock();
* try {</b>
* while (count == 0)
* <b>notEmpty.await();</b>
* Object x = items[takeptr];
* E x = (E) items[takeptr];
* if (++takeptr == items.length) takeptr = 0;
* --count;
* <b>notFull.signal();</b>
@ -310,7 +310,8 @@ public interface Condition {
* the following form:
*
* <pre> {@code
* boolean aMethod(long timeout, TimeUnit unit) {
* boolean aMethod(long timeout, TimeUnit unit)
* throws InterruptedException {
* long nanos = unit.toNanos(timeout);
* lock.lock();
* try {
@ -320,6 +321,7 @@ public interface Condition {
* nanos = theCondition.awaitNanos(nanos);
* }
* // ...
* return true;
* } finally {
* lock.unlock();
* }
@ -410,7 +412,8 @@ public interface Condition {
* <p>The return value indicates whether the deadline has elapsed,
* which can be used as follows:
* <pre> {@code
* boolean aMethod(Date deadline) {
* boolean aMethod(Date deadline)
* throws InterruptedException {
* boolean stillWaiting = true;
* lock.lock();
* try {
@ -420,6 +423,7 @@ public interface Condition {
* stillWaiting = theCondition.awaitUntil(deadline);
* }
* // ...
* return true;
* } finally {
* lock.unlock();
* }