mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-26 14:24:46 +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
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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() +
|
||||
|
|
|
@ -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>
|
||||
*
|
||||
|
|
|
@ -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<E> {
|
||||
* <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();
|
||||
* }
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue