--- a/jdk/.hgtags Mon Jul 24 11:54:57 2017 +0530
+++ b/jdk/.hgtags Tue Jul 25 14:07:37 2017 -0700
@@ -436,3 +436,4 @@
9f27d513658d5375b0e26846857d92563f279073 jdk-9+176
80acf577b7d0b886fb555c9916552844f6cc72af jdk-9+177
e069834e2c518a7bc2ffadc8c7e3cd7ec69fa8a0 jdk-10+15
+3281b964ab104002623d744e8b77a12269b70acd jdk-10+16
--- a/jdk/make/data/jdwp/jdwp.spec Mon Jul 24 11:54:57 2017 +0530
+++ b/jdk/make/data/jdwp/jdwp.spec Tue Jul 25 14:07:37 2017 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -1378,7 +1378,7 @@
(Repeat lines "The number of entries in the line table for this method."
(Group LineInfo
(long lineCodeIndex "Initial code index of the line, "
- "start <= lineCodeIndex < end")
+ "start <= lineCodeIndex < end")
(int lineNumber "Line number.")
)
)
@@ -1409,13 +1409,13 @@
"First code index at which the variable is visible (unsigned). "
"Used in conjunction with <code>length</code>. "
"The variable can be get or set only when the current "
- "<code>codeIndex</code> <= current frame code index < <code>codeIndex + length</code> ")
+ "<code>codeIndex</code> <= current frame code index < <code>codeIndex + length</code> ")
(string name "The variable's name.")
(string signature "The variable type's JNI signature.")
(int length
"Unsigned value used in conjunction with <code>codeIndex</code>. "
"The variable can be get or set only when the current "
- "<code>codeIndex</code> <= current frame code index < <code>code index + length</code> ")
+ "<code>codeIndex</code> <= current frame code index < <code>code index + length</code> ")
(int slot "The local variable's index in its frame")
)
)
@@ -1502,7 +1502,7 @@
"First code index at which the variable is visible (unsigned). "
"Used in conjunction with <code>length</code>. "
"The variable can be get or set only when the current "
- "<code>codeIndex</code> <= current frame code index < <code>codeIndex + length</code> ")
+ "<code>codeIndex</code> <= current frame code index < <code>codeIndex + length</code> ")
(string name "The variable's name.")
(string signature "The variable type's JNI signature.")
(string genericSignature "The variable type's generic "
@@ -1510,7 +1510,7 @@
(int length
"Unsigned value used in conjunction with <code>codeIndex</code>. "
"The variable can be get or set only when the current "
- "<code>codeIndex</code> <= current frame code index < <code>code index + length</code> ")
+ "<code>codeIndex</code> <= current frame code index < <code>code index + length</code> ")
(int slot "The local variable's index in its frame")
)
)
--- a/jdk/src/java.base/share/classes/java/util/ArrayDeque.java Mon Jul 24 11:54:57 2017 +0530
+++ b/jdk/src/java.base/share/classes/java/util/ArrayDeque.java Tue Jul 25 14:07:37 2017 -0700
@@ -243,7 +243,7 @@
* Index i must be logically ahead of index j.
* Precondition: 0 <= i < modulus, 0 <= j < modulus.
* @return the "circular distance" from j to i; corner case i == j
- * is diambiguated to "empty", returning 0.
+ * is disambiguated to "empty", returning 0.
*/
static final int sub(int i, int j, int modulus) {
if ((i -= j) < 0) i += modulus;
@@ -310,8 +310,7 @@
/**
* Adds all of the elements in the specified collection at the end
* of this deque, as if by calling {@link #addLast} on each one,
- * in the order that they are returned by the collection's
- * iterator.
+ * in the order that they are returned by the collection's iterator.
*
* @param c the elements to be inserted into this deque
* @return {@code true} if this deque changed as a result of the call
@@ -508,8 +507,8 @@
/**
* Retrieves and removes the head of the queue represented by this deque.
*
- * This method differs from {@link #poll poll} only in that it throws an
- * exception if this deque is empty.
+ * This method differs from {@link #poll() poll()} only in that it
+ * throws an exception if this deque is empty.
*
* <p>This method is equivalent to {@link #removeFirst}.
*
--- a/jdk/src/java.base/share/classes/java/util/ArrayList.java Mon Jul 24 11:54:57 2017 +0530
+++ b/jdk/src/java.base/share/classes/java/util/ArrayList.java Tue Jul 25 14:07:37 2017 -0700
@@ -514,15 +514,10 @@
*/
public E remove(int index) {
Objects.checkIndex(index, size);
-
- modCount++;
- E oldValue = elementData(index);
+ final Object[] es = elementData;
- int numMoved = size - index - 1;
- if (numMoved > 0)
- System.arraycopy(elementData, index+1, elementData, index,
- numMoved);
- elementData[--size] = null; // clear to let GC do its work
+ @SuppressWarnings("unchecked") E oldValue = (E) es[index];
+ fastRemove(es, index);
return oldValue;
}
@@ -541,33 +536,35 @@
* @return {@code true} if this list contained the specified element
*/
public boolean remove(Object o) {
- if (o == null) {
- for (int index = 0; index < size; index++)
- if (elementData[index] == null) {
- fastRemove(index);
- return true;
- }
- } else {
- for (int index = 0; index < size; index++)
- if (o.equals(elementData[index])) {
- fastRemove(index);
- return true;
- }
+ final Object[] es = elementData;
+ final int size = this.size;
+ int i = 0;
+ found: {
+ if (o == null) {
+ for (; i < size; i++)
+ if (es[i] == null)
+ break found;
+ } else {
+ for (; i < size; i++)
+ if (o.equals(es[i]))
+ break found;
+ }
+ return false;
}
- return false;
+ fastRemove(es, i);
+ return true;
}
/**
* Private remove method that skips bounds checking and does not
* return the value removed.
*/
- private void fastRemove(int index) {
+ private void fastRemove(Object[] es, int i) {
modCount++;
- int numMoved = size - index - 1;
- if (numMoved > 0)
- System.arraycopy(elementData, index+1, elementData, index,
- numMoved);
- elementData[--size] = null; // clear to let GC do its work
+ final int newSize;
+ if ((newSize = size - 1) > i)
+ System.arraycopy(es, i + 1, es, i, newSize - i);
+ es[size = newSize] = null;
}
/**
@@ -743,29 +740,30 @@
final int from, final int end) {
Objects.requireNonNull(c);
final Object[] es = elementData;
- final boolean modified;
int r;
// Optimize for initial run of survivors
- for (r = from; r < end && c.contains(es[r]) == complement; r++)
- ;
- if (modified = (r < end)) {
- int w = r++;
- try {
- for (Object e; r < end; r++)
- if (c.contains(e = es[r]) == complement)
- es[w++] = e;
- } catch (Throwable ex) {
- // Preserve behavioral compatibility with AbstractCollection,
- // even if c.contains() throws.
- System.arraycopy(es, r, es, w, end - r);
- w += end - r;
- throw ex;
- } finally {
- modCount += end - w;
- shiftTailOverGap(es, w, end);
- }
+ for (r = from;; r++) {
+ if (r == end)
+ return false;
+ if (c.contains(es[r]) != complement)
+ break;
}
- return modified;
+ int w = r++;
+ try {
+ for (Object e; r < end; r++)
+ if (c.contains(e = es[r]) == complement)
+ es[w++] = e;
+ } catch (Throwable ex) {
+ // Preserve behavioral compatibility with AbstractCollection,
+ // even if c.contains() throws.
+ System.arraycopy(es, r, es, w, end - r);
+ w += end - r;
+ throw ex;
+ } finally {
+ modCount += end - w;
+ shiftTailOverGap(es, w, end);
+ }
+ return true;
}
/**
@@ -784,7 +782,7 @@
int expectedModCount = modCount;
s.defaultWriteObject();
- // Write out size as capacity for behavioural compatibility with clone()
+ // Write out size as capacity for behavioral compatibility with clone()
s.writeInt(size);
// Write out all elements in the proper order.
--- a/jdk/src/java.base/share/classes/java/util/Queue.java Mon Jul 24 11:54:57 2017 +0530
+++ b/jdk/src/java.base/share/classes/java/util/Queue.java Tue Jul 25 14:07:37 2017 -0700
@@ -37,15 +37,14 @@
/**
* A collection designed for holding elements prior to processing.
- * Besides basic {@link java.util.Collection Collection} operations,
- * queues provide additional insertion, extraction, and inspection
- * operations. Each of these methods exists in two forms: one throws
- * an exception if the operation fails, the other returns a special
- * value (either {@code null} or {@code false}, depending on the
- * operation). The latter form of the insert operation is designed
- * specifically for use with capacity-restricted {@code Queue}
- * implementations; in most implementations, insert operations cannot
- * fail.
+ * Besides basic {@link Collection} operations, queues provide
+ * additional insertion, extraction, and inspection operations.
+ * Each of these methods exists in two forms: one throws an exception
+ * if the operation fails, the other returns a special value (either
+ * {@code null} or {@code false}, depending on the operation). The
+ * latter form of the insert operation is designed specifically for
+ * use with capacity-restricted {@code Queue} implementations; in most
+ * implementations, insert operations cannot fail.
*
* <table class="plain">
* <caption>Summary of Queue methods</caption>
@@ -56,18 +55,18 @@
* </tr>
* <tr>
* <td><b>Insert</b></td>
- * <td>{@link Queue#add add(e)}</td>
- * <td>{@link Queue#offer offer(e)}</td>
+ * <td>{@link #add(Object) add(e)}</td>
+ * <td>{@link #offer(Object) offer(e)}</td>
* </tr>
* <tr>
* <td><b>Remove</b></td>
- * <td>{@link Queue#remove remove()}</td>
- * <td>{@link Queue#poll poll()}</td>
+ * <td>{@link #remove() remove()}</td>
+ * <td>{@link #poll() poll()}</td>
* </tr>
* <tr>
* <td><b>Examine</b></td>
- * <td>{@link Queue#element element()}</td>
- * <td>{@link Queue#peek peek()}</td>
+ * <td>{@link #element() element()}</td>
+ * <td>{@link #peek() peek()}</td>
* </tr>
* </table>
*
@@ -77,7 +76,7 @@
* comparator, or the elements' natural ordering, and LIFO queues (or
* stacks) which order the elements LIFO (last-in-first-out).
* Whatever the ordering used, the <em>head</em> of the queue is that
- * element which would be removed by a call to {@link #remove() } or
+ * element which would be removed by a call to {@link #remove()} or
* {@link #poll()}. In a FIFO queue, all new elements are inserted at
* the <em>tail</em> of the queue. Other kinds of queues may use
* different placement rules. Every {@code Queue} implementation
@@ -173,8 +172,8 @@
/**
* Retrieves and removes the head of this queue. This method differs
- * from {@link #poll poll} only in that it throws an exception if this
- * queue is empty.
+ * from {@link #poll() poll()} only in that it throws an exception if
+ * this queue is empty.
*
* @return the head of this queue
* @throws NoSuchElementException if this queue is empty
--- a/jdk/src/java.base/share/classes/java/util/concurrent/BlockingDeque.java Mon Jul 24 11:54:57 2017 +0530
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/BlockingDeque.java Tue Jul 25 14:07:37 2017 -0700
@@ -67,22 +67,22 @@
* </tr>
* <tr>
* <td><b>Insert</b></td>
- * <td>{@link #addFirst addFirst(e)}</td>
+ * <td>{@link #addFirst(Object) addFirst(e)}</td>
* <td>{@link #offerFirst(Object) offerFirst(e)}</td>
- * <td>{@link #putFirst putFirst(e)}</td>
+ * <td>{@link #putFirst(Object) putFirst(e)}</td>
* <td>{@link #offerFirst(Object, long, TimeUnit) offerFirst(e, time, unit)}</td>
* </tr>
* <tr>
* <td><b>Remove</b></td>
- * <td>{@link #removeFirst removeFirst()}</td>
- * <td>{@link #pollFirst pollFirst()}</td>
- * <td>{@link #takeFirst takeFirst()}</td>
+ * <td>{@link #removeFirst() removeFirst()}</td>
+ * <td>{@link #pollFirst() pollFirst()}</td>
+ * <td>{@link #takeFirst() takeFirst()}</td>
* <td>{@link #pollFirst(long, TimeUnit) pollFirst(time, unit)}</td>
* </tr>
* <tr>
* <td><b>Examine</b></td>
- * <td>{@link #getFirst getFirst()}</td>
- * <td>{@link #peekFirst peekFirst()}</td>
+ * <td>{@link #getFirst() getFirst()}</td>
+ * <td>{@link #peekFirst() peekFirst()}</td>
* <td><em>not applicable</em></td>
* <td><em>not applicable</em></td>
* </tr>
@@ -98,22 +98,22 @@
* </tr>
* <tr>
* <td><b>Insert</b></td>
- * <td>{@link #addLast addLast(e)}</td>
+ * <td>{@link #addLast(Object) addLast(e)}</td>
* <td>{@link #offerLast(Object) offerLast(e)}</td>
- * <td>{@link #putLast putLast(e)}</td>
+ * <td>{@link #putLast(Object) putLast(e)}</td>
* <td>{@link #offerLast(Object, long, TimeUnit) offerLast(e, time, unit)}</td>
* </tr>
* <tr>
* <td><b>Remove</b></td>
* <td>{@link #removeLast() removeLast()}</td>
* <td>{@link #pollLast() pollLast()}</td>
- * <td>{@link #takeLast takeLast()}</td>
+ * <td>{@link #takeLast() takeLast()}</td>
* <td>{@link #pollLast(long, TimeUnit) pollLast(time, unit)}</td>
* </tr>
* <tr>
* <td><b>Examine</b></td>
- * <td>{@link #getLast getLast()}</td>
- * <td>{@link #peekLast peekLast()}</td>
+ * <td>{@link #getLast() getLast()}</td>
+ * <td>{@link #peekLast() peekLast()}</td>
* <td><em>not applicable</em></td>
* <td><em>not applicable</em></td>
* </tr>
@@ -512,7 +512,7 @@
/**
* Retrieves and removes the head of the queue represented by this deque
* (in other words, the first element of this deque).
- * This method differs from {@link #poll poll} only in that it
+ * This method differs from {@link #poll() poll()} only in that it
* throws an exception if this deque is empty.
*
* <p>This method is equivalent to {@link #removeFirst() removeFirst}.
@@ -563,7 +563,7 @@
/**
* Retrieves, but does not remove, the head of the queue represented by
* this deque (in other words, the first element of this deque).
- * This method differs from {@link #peek peek} only in that it throws an
+ * This method differs from {@link #peek() peek} only in that it throws an
* exception if this deque is empty.
*
* <p>This method is equivalent to {@link #getFirst() getFirst}.
--- a/jdk/src/java.base/share/classes/java/util/concurrent/BlockingQueue.java Mon Jul 24 11:54:57 2017 +0530
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/BlockingQueue.java Tue Jul 25 14:07:37 2017 -0700
@@ -39,10 +39,9 @@
import java.util.Queue;
/**
- * A {@link java.util.Queue} that additionally supports operations
- * that wait for the queue to become non-empty when retrieving an
- * element, and wait for space to become available in the queue when
- * storing an element.
+ * A {@link Queue} that additionally supports operations that wait for
+ * the queue to become non-empty when retrieving an element, and wait
+ * for space to become available in the queue when storing an element.
*
* <p>{@code BlockingQueue} methods come in four forms, with different ways
* of handling operations that cannot be satisfied immediately, but may be
@@ -64,22 +63,22 @@
* </tr>
* <tr>
* <td><b>Insert</b></td>
- * <td>{@link #add add(e)}</td>
- * <td>{@link #offer offer(e)}</td>
- * <td>{@link #put put(e)}</td>
+ * <td>{@link #add(Object) add(e)}</td>
+ * <td>{@link #offer(Object) offer(e)}</td>
+ * <td>{@link #put(Object) put(e)}</td>
* <td>{@link #offer(Object, long, TimeUnit) offer(e, time, unit)}</td>
* </tr>
* <tr>
* <td><b>Remove</b></td>
- * <td>{@link #remove remove()}</td>
- * <td>{@link #poll poll()}</td>
- * <td>{@link #take take()}</td>
+ * <td>{@link #remove() remove()}</td>
+ * <td>{@link #poll() poll()}</td>
+ * <td>{@link #take() take()}</td>
* <td>{@link #poll(long, TimeUnit) poll(time, unit)}</td>
* </tr>
* <tr>
* <td><b>Examine</b></td>
- * <td>{@link #element element()}</td>
- * <td>{@link #peek peek()}</td>
+ * <td>{@link #element() element()}</td>
+ * <td>{@link #peek() peek()}</td>
* <td><em>not applicable</em></td>
* <td><em>not applicable</em></td>
* </tr>
@@ -99,7 +98,7 @@
*
* <p>{@code BlockingQueue} implementations are designed to be used
* primarily for producer-consumer queues, but additionally support
- * the {@link java.util.Collection} interface. So, for example, it is
+ * the {@link Collection} interface. So, for example, it is
* possible to remove an arbitrary element from a queue using
* {@code remove(x)}. However, such operations are in general
* <em>not</em> performed very efficiently, and are intended for only
--- a/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java Mon Jul 24 11:54:57 2017 +0530
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java Tue Jul 25 14:07:37 2017 -0700
@@ -159,8 +159,7 @@
* ordering, or on any other objects or values that may transiently
* change while computation is in progress; and except for forEach
* actions, should ideally be side-effect-free. Bulk operations on
- * {@link java.util.Map.Entry} objects do not support method {@code
- * setValue}.
+ * {@link Map.Entry} objects do not support method {@code setValue}.
*
* <ul>
* <li>forEach: Performs a given action on each element.
--- a/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentMap.java Mon Jul 24 11:54:57 2017 +0530
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentMap.java Tue Jul 25 14:07:37 2017 -0700
@@ -42,8 +42,7 @@
import java.util.function.Function;
/**
- * A {@link java.util.Map} providing thread safety and atomicity
- * guarantees.
+ * A {@link Map} providing thread safety and atomicity guarantees.
*
* <p>To maintain the specified guarantees, default implementations of
* methods including {@link #putIfAbsent} inherited from {@link Map}
--- a/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java Mon Jul 24 11:54:57 2017 +0530
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java Tue Jul 25 14:07:37 2017 -0700
@@ -1821,9 +1821,11 @@
* The set's spliterator additionally reports {@link Spliterator#CONCURRENT},
* {@link Spliterator#NONNULL}, {@link Spliterator#SORTED} and
* {@link Spliterator#ORDERED}, with an encounter order that is ascending
- * key order. The spliterator's comparator (see
- * {@link java.util.Spliterator#getComparator()}) is {@code null} if
- * the map's comparator (see {@link #comparator()}) is {@code null}.
+ * key order.
+ *
+ * <p>The {@linkplain Spliterator#getComparator() spliterator's comparator}
+ * is {@code null} if the {@linkplain #comparator() map's comparator}
+ * is {@code null}.
* Otherwise, the spliterator's comparator is the same as or imposes the
* same total ordering as the map's comparator.
*
--- a/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java Mon Jul 24 11:54:57 2017 +0530
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java Tue Jul 25 14:07:37 2017 -0700
@@ -491,9 +491,9 @@
* encounter order that is ascending order. Overriding implementations
* should document the reporting of additional characteristic values.
*
- * <p>The spliterator's comparator (see
- * {@link java.util.Spliterator#getComparator()}) is {@code null} if
- * the set's comparator (see {@link #comparator()}) is {@code null}.
+ * <p>The {@linkplain Spliterator#getComparator() spliterator's comparator}
+ * is {@code null} if the {@linkplain #comparator() set's comparator}
+ * is {@code null}.
* Otherwise, the spliterator's comparator is the same as or imposes the
* same total ordering as the set's comparator.
*
--- a/jdk/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArraySet.java Mon Jul 24 11:54:57 2017 +0530
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArraySet.java Tue Jul 25 14:07:37 2017 -0700
@@ -46,7 +46,7 @@
import java.util.function.Predicate;
/**
- * A {@link java.util.Set} that uses an internal {@link CopyOnWriteArrayList}
+ * A {@link Set} that uses an internal {@link CopyOnWriteArrayList}
* for all of its operations. Thus, it shares the same basic properties:
* <ul>
* <li>It is best suited for applications in which set sizes generally
--- a/jdk/src/java.base/share/classes/java/util/concurrent/CountedCompleter.java Mon Jul 24 11:54:57 2017 +0530
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/CountedCompleter.java Tue Jul 25 14:07:37 2017 -0700
@@ -57,8 +57,7 @@
* decremented; otherwise, the completion action is performed, and if
* this completer itself has a completer, the process is continued
* with its completer. As is the case with related synchronization
- * components such as {@link java.util.concurrent.Phaser Phaser} and
- * {@link java.util.concurrent.Semaphore Semaphore}, these methods
+ * components such as {@link Phaser} and {@link Semaphore}, these methods
* affect only internal counts; they do not establish any further
* internal bookkeeping. In particular, the identities of pending
* tasks are not maintained. As illustrated below, you can create
--- a/jdk/src/java.base/share/classes/java/util/concurrent/DelayQueue.java Mon Jul 24 11:54:57 2017 +0530
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/DelayQueue.java Tue Jul 25 14:07:37 2017 -0700
@@ -323,39 +323,13 @@
}
/**
- * Returns first element only if it is expired.
- * Used only by drainTo. Call only when holding lock.
- */
- private E peekExpired() {
- // assert lock.isHeldByCurrentThread();
- E first = q.peek();
- return (first == null || first.getDelay(NANOSECONDS) > 0) ?
- null : first;
- }
-
- /**
* @throws UnsupportedOperationException {@inheritDoc}
* @throws ClassCastException {@inheritDoc}
* @throws NullPointerException {@inheritDoc}
* @throws IllegalArgumentException {@inheritDoc}
*/
public int drainTo(Collection<? super E> c) {
- Objects.requireNonNull(c);
- if (c == this)
- throw new IllegalArgumentException();
- final ReentrantLock lock = this.lock;
- lock.lock();
- try {
- int n = 0;
- for (E e; (e = peekExpired()) != null;) {
- c.add(e); // In this order, in case add() throws.
- q.poll();
- ++n;
- }
- return n;
- } finally {
- lock.unlock();
- }
+ return drainTo(c, Integer.MAX_VALUE);
}
/**
@@ -374,8 +348,11 @@
lock.lock();
try {
int n = 0;
- for (E e; n < maxElements && (e = peekExpired()) != null;) {
- c.add(e); // In this order, in case add() throws.
+ for (E first;
+ n < maxElements
+ && (first = q.peek()) != null
+ && first.getDelay(NANOSECONDS) <= 0;) {
+ c.add(first); // In this order, in case add() throws.
q.poll();
++n;
}
--- a/jdk/src/java.base/share/classes/java/util/concurrent/ForkJoinTask.java Mon Jul 24 11:54:57 2017 +0530
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/ForkJoinTask.java Tue Jul 25 14:07:37 2017 -0700
@@ -134,11 +134,11 @@
* {@link #isCompletedNormally} is true if a task completed without
* cancellation or encountering an exception; {@link #isCancelled} is
* true if the task was cancelled (in which case {@link #getException}
- * returns a {@link java.util.concurrent.CancellationException}); and
+ * returns a {@link CancellationException}); and
* {@link #isCompletedAbnormally} is true if a task was either
* cancelled or encountered an exception, in which case {@link
* #getException} will return either the encountered exception or
- * {@link java.util.concurrent.CancellationException}.
+ * {@link CancellationException}.
*
* <p>The ForkJoinTask class is not usually directly subclassed.
* Instead, you subclass one of the abstract classes that support a
@@ -695,13 +695,13 @@
}
/**
- * Returns the result of the computation when it {@link #isDone is
- * done}. This method differs from {@link #get()} in that
- * abnormal completion results in {@code RuntimeException} or
- * {@code Error}, not {@code ExecutionException}, and that
- * interrupts of the calling thread do <em>not</em> cause the
- * method to abruptly return by throwing {@code
- * InterruptedException}.
+ * Returns the result of the computation when it
+ * {@linkplain #isDone is done}.
+ * This method differs from {@link #get()} in that abnormal
+ * completion results in {@code RuntimeException} or {@code Error},
+ * not {@code ExecutionException}, and that interrupts of the
+ * calling thread do <em>not</em> cause the method to abruptly
+ * return by throwing {@code InterruptedException}.
*
* @return the computed result
*/
--- a/jdk/src/java.base/share/classes/java/util/concurrent/LinkedBlockingDeque.java Mon Jul 24 11:54:57 2017 +0530
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/LinkedBlockingDeque.java Tue Jul 25 14:07:37 2017 -0700
@@ -651,7 +651,7 @@
/**
* Retrieves and removes the head of the queue represented by this deque.
- * This method differs from {@link #poll poll} only in that it throws an
+ * This method differs from {@link #poll() poll()} only in that it throws an
* exception if this deque is empty.
*
* <p>This method is equivalent to {@link #removeFirst() removeFirst}.
@@ -677,7 +677,7 @@
/**
* Retrieves, but does not remove, the head of the queue represented by
- * this deque. This method differs from {@link #peek peek} only in that
+ * this deque. This method differs from {@link #peek() peek()} only in that
* it throws an exception if this deque is empty.
*
* <p>This method is equivalent to {@link #getFirst() getFirst}.
--- a/jdk/src/java.base/share/classes/java/util/concurrent/LinkedTransferQueue.java Mon Jul 24 11:54:57 2017 +0530
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/LinkedTransferQueue.java Tue Jul 25 14:07:37 2017 -0700
@@ -1275,8 +1275,7 @@
* return {@code false}.
*
* @return {@code true} (as specified by
- * {@link java.util.concurrent.BlockingQueue#offer(Object,long,TimeUnit)
- * BlockingQueue.offer})
+ * {@link BlockingQueue#offer(Object,long,TimeUnit) BlockingQueue.offer})
* @throws NullPointerException if the specified element is null
*/
public boolean offer(E e, long timeout, TimeUnit unit) {
@@ -1567,8 +1566,7 @@
* {@code LinkedTransferQueue} is not capacity constrained.
*
* @return {@code Integer.MAX_VALUE} (as specified by
- * {@link java.util.concurrent.BlockingQueue#remainingCapacity()
- * BlockingQueue.remainingCapacity})
+ * {@link BlockingQueue#remainingCapacity()})
*/
public int remainingCapacity() {
return Integer.MAX_VALUE;
--- a/jdk/src/java.base/share/classes/java/util/concurrent/Phaser.java Mon Jul 24 11:54:57 2017 +0530
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/Phaser.java Tue Jul 25 14:07:37 2017 -0700
@@ -42,9 +42,8 @@
/**
* A reusable synchronization barrier, similar in functionality to
- * {@link java.util.concurrent.CyclicBarrier CyclicBarrier} and
- * {@link java.util.concurrent.CountDownLatch CountDownLatch}
- * but supporting more flexible usage.
+ * {@link CyclicBarrier} and {@link CountDownLatch} but supporting
+ * more flexible usage.
*
* <p><b>Registration.</b> Unlike the case for other barriers, the
* number of parties <em>registered</em> to synchronize on a phaser
--- a/jdk/src/java.base/share/classes/java/util/concurrent/ScheduledExecutorService.java Mon Jul 24 11:54:57 2017 +0530
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/ScheduledExecutorService.java Tue Jul 25 14:07:37 2017 -0700
@@ -80,7 +80,7 @@
* Runnable beeper = () -> System.out.println("beep");
* ScheduledFuture<?> beeperHandle =
* scheduler.scheduleAtFixedRate(beeper, 10, 10, SECONDS);
- * Runnable canceller = () -> beeperHandle.cancel(true);
+ * Runnable canceller = () -> beeperHandle.cancel(false);
* scheduler.schedule(canceller, 1, HOURS);
* }
* }}</pre>
@@ -91,8 +91,7 @@
public interface ScheduledExecutorService extends ExecutorService {
/**
- * Creates and executes a one-shot action that becomes enabled
- * after the given delay.
+ * Submits a one-shot task that becomes enabled after the given delay.
*
* @param command the task to execute
* @param delay the time from now to delay execution
@@ -102,14 +101,14 @@
* {@code null} upon completion
* @throws RejectedExecutionException if the task cannot be
* scheduled for execution
- * @throws NullPointerException if command is null
+ * @throws NullPointerException if command or unit is null
*/
public ScheduledFuture<?> schedule(Runnable command,
long delay, TimeUnit unit);
/**
- * Creates and executes a ScheduledFuture that becomes enabled after the
- * given delay.
+ * Submits a value-returning one-shot task that becomes enabled
+ * after the given delay.
*
* @param callable the function to execute
* @param delay the time from now to delay execution
@@ -118,15 +117,15 @@
* @return a ScheduledFuture that can be used to extract result or cancel
* @throws RejectedExecutionException if the task cannot be
* scheduled for execution
- * @throws NullPointerException if callable is null
+ * @throws NullPointerException if callable or unit is null
*/
public <V> ScheduledFuture<V> schedule(Callable<V> callable,
long delay, TimeUnit unit);
/**
- * Creates and executes a periodic action that becomes enabled first
- * after the given initial delay, and subsequently with the given
- * period; that is, executions will commence after
+ * Submits a periodic action that becomes enabled first after the
+ * given initial delay, and subsequently with the given period;
+ * that is, executions will commence after
* {@code initialDelay}, then {@code initialDelay + period}, then
* {@code initialDelay + 2 * period}, and so on.
*
@@ -137,8 +136,8 @@
* via the returned future.
* <li>The executor terminates, also resulting in task cancellation.
* <li>An execution of the task throws an exception. In this case
- * calling {@link Future#get() get} on the returned future will
- * throw {@link ExecutionException}.
+ * calling {@link Future#get() get} on the returned future will throw
+ * {@link ExecutionException}, holding the exception as its cause.
* </ul>
* Subsequent executions are suppressed. Subsequent calls to
* {@link Future#isDone isDone()} on the returned future will
@@ -159,7 +158,7 @@
* abnormal termination of a task execution.
* @throws RejectedExecutionException if the task cannot be
* scheduled for execution
- * @throws NullPointerException if command is null
+ * @throws NullPointerException if command or unit is null
* @throws IllegalArgumentException if period less than or equal to zero
*/
public ScheduledFuture<?> scheduleAtFixedRate(Runnable command,
@@ -168,10 +167,10 @@
TimeUnit unit);
/**
- * Creates and executes a periodic action that becomes enabled first
- * after the given initial delay, and subsequently with the
- * given delay between the termination of one execution and the
- * commencement of the next.
+ * Submits a periodic action that becomes enabled first after the
+ * given initial delay, and subsequently with the given delay
+ * between the termination of one execution and the commencement of
+ * the next.
*
* <p>The sequence of task executions continues indefinitely until
* one of the following exceptional completions occur:
@@ -180,8 +179,8 @@
* via the returned future.
* <li>The executor terminates, also resulting in task cancellation.
* <li>An execution of the task throws an exception. In this case
- * calling {@link Future#get() get} on the returned future will
- * throw {@link ExecutionException}.
+ * calling {@link Future#get() get} on the returned future will throw
+ * {@link ExecutionException}, holding the exception as its cause.
* </ul>
* Subsequent executions are suppressed. Subsequent calls to
* {@link Future#isDone isDone()} on the returned future will
@@ -199,7 +198,7 @@
* abnormal termination of a task execution.
* @throws RejectedExecutionException if the task cannot be
* scheduled for execution
- * @throws NullPointerException if command is null
+ * @throws NullPointerException if command or unit is null
* @throws IllegalArgumentException if delay less than or equal to zero
*/
public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command,
--- a/jdk/src/java.base/share/classes/java/util/concurrent/ScheduledThreadPoolExecutor.java Mon Jul 24 11:54:57 2017 +0530
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/ScheduledThreadPoolExecutor.java Tue Jul 25 14:07:37 2017 -0700
@@ -44,6 +44,7 @@
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
+import java.util.Objects;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
@@ -87,6 +88,11 @@
* use {@code allowCoreThreadTimeOut} because this may leave the pool
* without threads to handle tasks once they become eligible to run.
*
+ * <p>As with {@code ThreadPoolExecutor}, if not otherwise specified,
+ * this class uses {@link Executors#defaultThreadFactory} as the
+ * default thread factory, and {@link ThreadPoolExecutor.AbortPolicy}
+ * as the default rejected execution handler.
+ *
* <p><b>Extension notes:</b> This class overrides the
* {@link ThreadPoolExecutor#execute(Runnable) execute} and
* {@link AbstractExecutorService#submit(Runnable) submit}
@@ -161,7 +167,7 @@
private volatile boolean continueExistingPeriodicTasksAfterShutdown;
/**
- * False if should cancel non-periodic tasks on shutdown.
+ * False if should cancel non-periodic not-yet-expired tasks on shutdown.
*/
private volatile boolean executeExistingDelayedTasksAfterShutdown = true;
@@ -292,10 +298,9 @@
* Overrides FutureTask version so as to reset/requeue if periodic.
*/
public void run() {
- boolean periodic = isPeriodic();
- if (!canRunInCurrentRunState(periodic))
+ if (!canRunInCurrentRunState(this))
cancel(false);
- else if (!periodic)
+ else if (!isPeriodic())
super.run();
else if (super.runAndReset()) {
setNextRunTime();
@@ -305,15 +310,18 @@
}
/**
- * Returns true if can run a task given current run state
- * and run-after-shutdown parameters.
- *
- * @param periodic true if this task periodic, false if delayed
+ * Returns true if can run a task given current run state and
+ * run-after-shutdown parameters.
*/
- boolean canRunInCurrentRunState(boolean periodic) {
- return isRunningOrShutdown(periodic ?
- continueExistingPeriodicTasksAfterShutdown :
- executeExistingDelayedTasksAfterShutdown);
+ boolean canRunInCurrentRunState(RunnableScheduledFuture<?> task) {
+ if (!isShutdown())
+ return true;
+ if (isStopped())
+ return false;
+ return task.isPeriodic()
+ ? continueExistingPeriodicTasksAfterShutdown
+ : (executeExistingDelayedTasksAfterShutdown
+ || task.getDelay(NANOSECONDS) <= 0);
}
/**
@@ -332,9 +340,7 @@
reject(task);
else {
super.getQueue().add(task);
- if (isShutdown() &&
- !canRunInCurrentRunState(task.isPeriodic()) &&
- remove(task))
+ if (!canRunInCurrentRunState(task) && remove(task))
task.cancel(false);
else
ensurePrestart();
@@ -348,13 +354,14 @@
* @param task the task
*/
void reExecutePeriodic(RunnableScheduledFuture<?> task) {
- if (canRunInCurrentRunState(true)) {
+ if (canRunInCurrentRunState(task)) {
super.getQueue().add(task);
- if (!canRunInCurrentRunState(true) && remove(task))
- task.cancel(false);
- else
+ if (canRunInCurrentRunState(task) || !remove(task)) {
ensurePrestart();
+ return;
+ }
}
+ task.cancel(false);
}
/**
@@ -367,23 +374,18 @@
getExecuteExistingDelayedTasksAfterShutdownPolicy();
boolean keepPeriodic =
getContinueExistingPeriodicTasksAfterShutdownPolicy();
- if (!keepDelayed && !keepPeriodic) {
- for (Object e : q.toArray())
- if (e instanceof RunnableScheduledFuture<?>)
- ((RunnableScheduledFuture<?>) e).cancel(false);
- q.clear();
- }
- else {
- // Traverse snapshot to avoid iterator exceptions
- for (Object e : q.toArray()) {
- if (e instanceof RunnableScheduledFuture) {
- RunnableScheduledFuture<?> t =
- (RunnableScheduledFuture<?>)e;
- if ((t.isPeriodic() ? !keepPeriodic : !keepDelayed) ||
- t.isCancelled()) { // also remove if already cancelled
- if (q.remove(t))
- t.cancel(false);
- }
+ // Traverse snapshot to avoid iterator exceptions
+ // TODO: implement and use efficient removeIf
+ // super.getQueue().removeIf(...);
+ for (Object e : q.toArray()) {
+ if (e instanceof RunnableScheduledFuture) {
+ RunnableScheduledFuture<?> t = (RunnableScheduledFuture<?>)e;
+ if ((t.isPeriodic()
+ ? !keepPeriodic
+ : (!keepDelayed && t.getDelay(NANOSECONDS) > 0))
+ || t.isCancelled()) { // also remove if already cancelled
+ if (q.remove(t))
+ t.cancel(false);
}
}
}
@@ -579,6 +581,34 @@
}
/**
+ * Submits a periodic action that becomes enabled first after the
+ * given initial delay, and subsequently with the given period;
+ * that is, executions will commence after
+ * {@code initialDelay}, then {@code initialDelay + period}, then
+ * {@code initialDelay + 2 * period}, and so on.
+ *
+ * <p>The sequence of task executions continues indefinitely until
+ * one of the following exceptional completions occur:
+ * <ul>
+ * <li>The task is {@linkplain Future#cancel explicitly cancelled}
+ * via the returned future.
+ * <li>Method {@link #shutdown} is called and the {@linkplain
+ * #getContinueExistingPeriodicTasksAfterShutdownPolicy policy on
+ * whether to continue after shutdown} is not set true, or method
+ * {@link #shutdownNow} is called; also resulting in task
+ * cancellation.
+ * <li>An execution of the task throws an exception. In this case
+ * calling {@link Future#get() get} on the returned future will throw
+ * {@link ExecutionException}, holding the exception as its cause.
+ * </ul>
+ * Subsequent executions are suppressed. Subsequent calls to
+ * {@link Future#isDone isDone()} on the returned future will
+ * return {@code true}.
+ *
+ * <p>If any execution of this task takes longer than its period, then
+ * subsequent executions may start late, but will not concurrently
+ * execute.
+ *
* @throws RejectedExecutionException {@inheritDoc}
* @throws NullPointerException {@inheritDoc}
* @throws IllegalArgumentException {@inheritDoc}
@@ -604,6 +634,29 @@
}
/**
+ * Submits a periodic action that becomes enabled first after the
+ * given initial delay, and subsequently with the given delay
+ * between the termination of one execution and the commencement of
+ * the next.
+ *
+ * <p>The sequence of task executions continues indefinitely until
+ * one of the following exceptional completions occur:
+ * <ul>
+ * <li>The task is {@linkplain Future#cancel explicitly cancelled}
+ * via the returned future.
+ * <li>Method {@link #shutdown} is called and the {@linkplain
+ * #getContinueExistingPeriodicTasksAfterShutdownPolicy policy on
+ * whether to continue after shutdown} is not set true, or method
+ * {@link #shutdownNow} is called; also resulting in task
+ * cancellation.
+ * <li>An execution of the task throws an exception. In this case
+ * calling {@link Future#get() get} on the returned future will throw
+ * {@link ExecutionException}, holding the exception as its cause.
+ * </ul>
+ * Subsequent executions are suppressed. Subsequent calls to
+ * {@link Future#isDone isDone()} on the returned future will
+ * return {@code true}.
+ *
* @throws RejectedExecutionException {@inheritDoc}
* @throws NullPointerException {@inheritDoc}
* @throws IllegalArgumentException {@inheritDoc}
@@ -681,9 +734,8 @@
/**
* Sets the policy on whether to continue executing existing
* periodic tasks even when this executor has been {@code shutdown}.
- * In this case, these tasks will only terminate upon
- * {@code shutdownNow} or after setting the policy to
- * {@code false} when already shutdown.
+ * In this case, executions will continue until {@code shutdownNow}
+ * or the policy is set to {@code false} when already shutdown.
* This value is by default {@code false}.
*
* @param value if {@code true}, continue after shutdown, else don't
@@ -698,9 +750,8 @@
/**
* Gets the policy on whether to continue executing existing
* periodic tasks even when this executor has been {@code shutdown}.
- * In this case, these tasks will only terminate upon
- * {@code shutdownNow} or after setting the policy to
- * {@code false} when already shutdown.
+ * In this case, executions will continue until {@code shutdownNow}
+ * or the policy is set to {@code false} when already shutdown.
* This value is by default {@code false}.
*
* @return {@code true} if will continue after shutdown
@@ -904,7 +955,7 @@
/**
* Sets f's heapIndex if it is a ScheduledFutureTask.
*/
- private void setIndex(RunnableScheduledFuture<?> f, int idx) {
+ private static void setIndex(RunnableScheduledFuture<?> f, int idx) {
if (f instanceof ScheduledFutureTask)
((ScheduledFutureTask)f).heapIndex = idx;
}
@@ -1202,41 +1253,12 @@
}
}
- /**
- * Returns first element only if it is expired.
- * Used only by drainTo. Call only when holding lock.
- */
- private RunnableScheduledFuture<?> peekExpired() {
- // assert lock.isHeldByCurrentThread();
- RunnableScheduledFuture<?> first = queue[0];
- return (first == null || first.getDelay(NANOSECONDS) > 0) ?
- null : first;
- }
-
public int drainTo(Collection<? super Runnable> c) {
- if (c == null)
- throw new NullPointerException();
- if (c == this)
- throw new IllegalArgumentException();
- final ReentrantLock lock = this.lock;
- lock.lock();
- try {
- RunnableScheduledFuture<?> first;
- int n = 0;
- while ((first = peekExpired()) != null) {
- c.add(first); // In this order, in case add() throws.
- finishPoll(first);
- ++n;
- }
- return n;
- } finally {
- lock.unlock();
- }
+ return drainTo(c, Integer.MAX_VALUE);
}
public int drainTo(Collection<? super Runnable> c, int maxElements) {
- if (c == null)
- throw new NullPointerException();
+ Objects.requireNonNull(c);
if (c == this)
throw new IllegalArgumentException();
if (maxElements <= 0)
@@ -1244,9 +1266,11 @@
final ReentrantLock lock = this.lock;
lock.lock();
try {
- RunnableScheduledFuture<?> first;
int n = 0;
- while (n < maxElements && (first = peekExpired()) != null) {
+ for (RunnableScheduledFuture<?> first;
+ n < maxElements
+ && (first = queue[0]) != null
+ && first.getDelay(NANOSECONDS) <= 0;) {
c.add(first); // In this order, in case add() throws.
finishPoll(first);
++n;
@@ -1284,7 +1308,13 @@
}
public Iterator<Runnable> iterator() {
- return new Itr(Arrays.copyOf(queue, size));
+ final ReentrantLock lock = this.lock;
+ lock.lock();
+ try {
+ return new Itr(Arrays.copyOf(queue, size));
+ } finally {
+ lock.unlock();
+ }
}
/**
--- a/jdk/src/java.base/share/classes/java/util/concurrent/Semaphore.java Mon Jul 24 11:54:57 2017 +0530
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/Semaphore.java Tue Jul 25 14:07:37 2017 -0700
@@ -359,7 +359,7 @@
* This "barging" behavior can be useful in certain
* circumstances, even though it breaks fairness. If you want to honor
* the fairness setting, then use
- * {@link #tryAcquire(long, TimeUnit) tryAcquire(0, TimeUnit.SECONDS) }
+ * {@link #tryAcquire(long, TimeUnit) tryAcquire(0, TimeUnit.SECONDS)}
* which is almost equivalent (it also detects interruption).
*
* @return {@code true} if a permit was acquired and {@code false}
@@ -523,7 +523,7 @@
* "barging" behavior can be useful in certain
* circumstances, even though it breaks fairness. If you want to
* honor the fairness setting, then use {@link #tryAcquire(int,
- * long, TimeUnit) tryAcquire(permits, 0, TimeUnit.SECONDS) }
+ * long, TimeUnit) tryAcquire(permits, 0, TimeUnit.SECONDS)}
* which is almost equivalent (it also detects interruption).
*
* @param permits the number of permits to acquire
--- a/jdk/src/java.base/share/classes/java/util/concurrent/SynchronousQueue.java Mon Jul 24 11:54:57 2017 +0530
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/SynchronousQueue.java Tue Jul 25 14:07:37 2017 -0700
@@ -1066,7 +1066,7 @@
/**
* Returns an empty spliterator in which calls to
- * {@link java.util.Spliterator#trySplit()} always return {@code null}.
+ * {@link Spliterator#trySplit() trySplit} always return {@code null}.
*
* @return an empty spliterator
* @since 1.8
--- a/jdk/src/java.base/share/classes/java/util/concurrent/ThreadPoolExecutor.java Mon Jul 24 11:54:57 2017 +0530
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/ThreadPoolExecutor.java Tue Jul 25 14:07:37 2017 -0700
@@ -74,31 +74,28 @@
*
* <dt>Core and maximum pool sizes</dt>
*
- * <dd style="font-family:'DejaVu Sans', Arial, Helvetica, sans-serif">
- * A {@code ThreadPoolExecutor} will automatically adjust the
+ * <dd>A {@code ThreadPoolExecutor} will automatically adjust the
* pool size (see {@link #getPoolSize})
* according to the bounds set by
* corePoolSize (see {@link #getCorePoolSize}) and
* maximumPoolSize (see {@link #getMaximumPoolSize}).
*
* When a new task is submitted in method {@link #execute(Runnable)},
- * and fewer than corePoolSize threads are running, a new thread is
+ * if fewer than corePoolSize threads are running, a new thread is
* created to handle the request, even if other worker threads are
- * idle. If there are more than corePoolSize but less than
- * maximumPoolSize threads running, a new thread will be created only
- * if the queue is full. By setting corePoolSize and maximumPoolSize
- * the same, you create a fixed-size thread pool. By setting
- * maximumPoolSize to an essentially unbounded value such as {@code
- * Integer.MAX_VALUE}, you allow the pool to accommodate an arbitrary
- * number of concurrent tasks. Most typically, core and maximum pool
- * sizes are set only upon construction, but they may also be changed
- * dynamically using {@link #setCorePoolSize} and {@link
- * #setMaximumPoolSize}. </dd>
+ * idle. Else if fewer than maximumPoolSize threads are running, a
+ * new thread will be created to handle the request only if the queue
+ * is full. By setting corePoolSize and maximumPoolSize the same, you
+ * create a fixed-size thread pool. By setting maximumPoolSize to an
+ * essentially unbounded value such as {@code Integer.MAX_VALUE}, you
+ * allow the pool to accommodate an arbitrary number of concurrent
+ * tasks. Most typically, core and maximum pool sizes are set only
+ * upon construction, but they may also be changed dynamically using
+ * {@link #setCorePoolSize} and {@link #setMaximumPoolSize}. </dd>
*
* <dt>On-demand construction</dt>
*
- * <dd style="font-family:'DejaVu Sans', Arial, Helvetica, sans-serif">
- * By default, even core threads are initially created and
+ * <dd>By default, even core threads are initially created and
* started only when new tasks arrive, but this can be overridden
* dynamically using method {@link #prestartCoreThread} or {@link
* #prestartAllCoreThreads}. You probably want to prestart threads if
@@ -106,8 +103,7 @@
*
* <dt>Creating new threads</dt>
*
- * <dd style="font-family:'DejaVu Sans', Arial, Helvetica, sans-serif">
- * New threads are created using a {@link ThreadFactory}. If not
+ * <dd>New threads are created using a {@link ThreadFactory}. If not
* otherwise specified, a {@link Executors#defaultThreadFactory} is
* used, that creates threads to all be in the same {@link
* ThreadGroup} and with the same {@code NORM_PRIORITY} priority and
@@ -124,8 +120,7 @@
*
* <dt>Keep-alive times</dt>
*
- * <dd style="font-family:'DejaVu Sans', Arial, Helvetica, sans-serif">
- * If the pool currently has more than corePoolSize threads,
+ * <dd>If the pool currently has more than corePoolSize threads,
* excess threads will be terminated if they have been idle for more
* than the keepAliveTime (see {@link #getKeepAliveTime(TimeUnit)}).
* This provides a means of reducing resource consumption when the
@@ -142,8 +137,7 @@
*
* <dt>Queuing</dt>
*
- * <dd style="font-family:'DejaVu Sans', Arial, Helvetica, sans-serif">
- * Any {@link BlockingQueue} may be used to transfer and hold
+ * <dd>Any {@link BlockingQueue} may be used to transfer and hold
* submitted tasks. The use of this queue interacts with pool sizing:
*
* <ul>
@@ -208,8 +202,7 @@
*
* <dt>Rejected tasks</dt>
*
- * <dd style="font-family:'DejaVu Sans', Arial, Helvetica, sans-serif">
- * New tasks submitted in method {@link #execute(Runnable)} will be
+ * <dd>New tasks submitted in method {@link #execute(Runnable)} will be
* <em>rejected</em> when the Executor has been shut down, and also when
* the Executor uses finite bounds for both maximum threads and work queue
* capacity, and is saturated. In either case, the {@code execute} method
@@ -220,9 +213,8 @@
*
* <ol>
*
- * <li>In the default {@link ThreadPoolExecutor.AbortPolicy}, the
- * handler throws a runtime {@link RejectedExecutionException} upon
- * rejection.
+ * <li>In the default {@link ThreadPoolExecutor.AbortPolicy}, the handler
+ * throws a runtime {@link RejectedExecutionException} upon rejection.
*
* <li>In {@link ThreadPoolExecutor.CallerRunsPolicy}, the thread
* that invokes {@code execute} itself runs the task. This provides a
@@ -246,8 +238,7 @@
*
* <dt>Hook methods</dt>
*
- * <dd style="font-family:'DejaVu Sans', Arial, Helvetica, sans-serif">
- * This class provides {@code protected} overridable
+ * <dd>This class provides {@code protected} overridable
* {@link #beforeExecute(Thread, Runnable)} and
* {@link #afterExecute(Runnable, Throwable)} methods that are called
* before and after execution of each task. These can be used to
@@ -263,8 +254,7 @@
*
* <dt>Queue maintenance</dt>
*
- * <dd style="font-family:'DejaVu Sans', Arial, Helvetica, sans-serif">
- * Method {@link #getQueue()} allows access to the work queue
+ * <dd>Method {@link #getQueue()} allows access to the work queue
* for purposes of monitoring and debugging. Use of this method for
* any other purpose is strongly discouraged. Two supplied methods,
* {@link #remove(Runnable)} and {@link #purge} are available to
@@ -273,8 +263,7 @@
*
* <dt>Finalization</dt>
*
- * <dd style="font-family:'DejaVu Sans', Arial, Helvetica, sans-serif">
- * A pool that is no longer referenced in a program <em>AND</em>
+ * <dd>A pool that is no longer referenced in a program <em>AND</em>
* has no remaining threads will be {@code shutdown} automatically. If
* you would like to ensure that unreferenced pools are reclaimed even
* if users forget to call {@link #shutdown}, then you must arrange
@@ -851,17 +840,6 @@
}
/**
- * State check needed by ScheduledThreadPoolExecutor to
- * enable running tasks during shutdown.
- *
- * @param shutdownOK true if should return true if SHUTDOWN
- */
- final boolean isRunningOrShutdown(boolean shutdownOK) {
- int rs = runStateOf(ctl.get());
- return rs == RUNNING || (rs == SHUTDOWN && shutdownOK);
- }
-
- /**
* Drains the task queue into a new list, normally using
* drainTo. But if the queue is a DelayQueue or any other kind of
* queue for which poll or drainTo may fail to remove some
@@ -1184,9 +1162,11 @@
/**
* Creates a new {@code ThreadPoolExecutor} with the given initial
- * parameters and default thread factory and rejected execution handler.
- * It may be more convenient to use one of the {@link Executors} factory
- * methods instead of this general purpose constructor.
+ * parameters, the default thread factory and the default rejected
+ * execution handler.
+ *
+ * <p>It may be more convenient to use one of the {@link Executors}
+ * factory methods instead of this general purpose constructor.
*
* @param corePoolSize the number of threads to keep in the pool, even
* if they are idle, unless {@code allowCoreThreadTimeOut} is set
@@ -1217,7 +1197,8 @@
/**
* Creates a new {@code ThreadPoolExecutor} with the given initial
- * parameters and default rejected execution handler.
+ * parameters and {@linkplain ThreadPoolExecutor.AbortPolicy
+ * default rejected execution handler}.
*
* @param corePoolSize the number of threads to keep in the pool, even
* if they are idle, unless {@code allowCoreThreadTimeOut} is set
@@ -1252,7 +1233,8 @@
/**
* Creates a new {@code ThreadPoolExecutor} with the given initial
- * parameters and default thread factory.
+ * parameters and
+ * {@linkplain Executors#defaultThreadFactory default thread factory}.
*
* @param corePoolSize the number of threads to keep in the pool, even
* if they are idle, unless {@code allowCoreThreadTimeOut} is set
@@ -1450,6 +1432,11 @@
return ! isRunning(ctl.get());
}
+ /** Used by ScheduledThreadPoolExecutor. */
+ boolean isStopped() {
+ return runStateAtLeast(ctl.get(), STOP);
+ }
+
/**
* Returns true if this executor is in the process of terminating
* after {@link #shutdown} or {@link #shutdownNow} but has not
@@ -2065,7 +2052,10 @@
/**
* A handler for rejected tasks that throws a
- * {@code RejectedExecutionException}.
+ * {@link RejectedExecutionException}.
+ *
+ * This is the default handler for {@link ThreadPoolExecutor} and
+ * {@link ScheduledThreadPoolExecutor}.
*/
public static class AbortPolicy implements RejectedExecutionHandler {
/**
--- a/jdk/src/java.base/share/classes/java/util/concurrent/TimeUnit.java Mon Jul 24 11:54:57 2017 +0530
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/TimeUnit.java Tue Jul 25 14:07:37 2017 -0700
@@ -337,8 +337,8 @@
* This is a convenience method that converts timeout arguments
* into the form required by the {@code Object.wait} method.
*
- * <p>For example, you could implement a blocking {@code poll}
- * method (see {@link BlockingQueue#poll BlockingQueue.poll})
+ * <p>For example, you could implement a blocking {@code poll} method
+ * (see {@link BlockingQueue#poll(long, TimeUnit) BlockingQueue.poll})
* using:
*
* <pre> {@code
--- a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/DoubleAccumulator.java Mon Jul 24 11:54:57 2017 +0530
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/DoubleAccumulator.java Tue Jul 25 14:07:37 2017 -0700
@@ -56,11 +56,13 @@
*
* <p>The supplied accumulator function should be side-effect-free,
* since it may be re-applied when attempted updates fail due to
- * contention among threads. The function is applied with the current
- * value as its first argument, and the given update as the second
- * argument. For example, to maintain a running maximum value, you
- * could supply {@code Double::max} along with {@code
- * Double.NEGATIVE_INFINITY} as the identity. The order of
+ * contention among threads. For predictable results, the accumulator
+ * function should be commutative and associative within the floating
+ * point tolerance required in usage contexts. The function is applied
+ * with an existing value (or identity) as one argument, and a given
+ * update as the other argument. For example, to maintain a running
+ * maximum value, you could supply {@code Double::max} along with
+ * {@code Double.NEGATIVE_INFINITY} as the identity. The order of
* accumulation within or across threads is not guaranteed. Thus, this
* class may not be applicable if numerical stability is required,
* especially when combining values of substantially different orders
--- a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/LongAccumulator.java Mon Jul 24 11:54:57 2017 +0530
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/LongAccumulator.java Tue Jul 25 14:07:37 2017 -0700
@@ -59,11 +59,12 @@
* applicable to functions for which the order of accumulation does
* not matter. The supplied accumulator function should be
* side-effect-free, since it may be re-applied when attempted updates
- * fail due to contention among threads. The function is applied with
- * the current value as its first argument, and the given update as
- * the second argument. For example, to maintain a running maximum
- * value, you could supply {@code Long::max} along with {@code
- * Long.MIN_VALUE} as the identity.
+ * fail due to contention among threads. For predictable results, the
+ * accumulator function should be associative and commutative. The
+ * function is applied with an existing value (or identity) as one
+ * argument, and a given update as the other argument. For example,
+ * to maintain a running maximum value, you could supply {@code
+ * Long::max} along with {@code Long.MIN_VALUE} as the identity.
*
* <p>Class {@link LongAdder} provides analogs of the functionality of
* this class for the common special case of maintaining counts and
--- a/jdk/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java Mon Jul 24 11:54:57 2017 +0530
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java Tue Jul 25 14:07:37 2017 -0700
@@ -113,8 +113,7 @@
* @param newState the new state value
*/
protected final void setState(long newState) {
- // Use putLongVolatile instead of ordinary volatile store when
- // using compareAndSwapLong, for sake of some 32bit systems.
+ // See JDK-8180620: Clarify VarHandle mixed-access subtleties
STATE.setVolatile(this, newState);
}
--- a/jdk/src/java.base/share/classes/java/util/concurrent/locks/ReentrantLock.java Mon Jul 24 11:54:57 2017 +0530
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/locks/ReentrantLock.java Tue Jul 25 14:07:37 2017 -0700
@@ -330,7 +330,7 @@
* This "barging" behavior can be useful in certain
* circumstances, even though it breaks fairness. If you want to honor
* the fairness setting for this lock, then use
- * {@link #tryLock(long, TimeUnit) tryLock(0, TimeUnit.SECONDS) }
+ * {@link #tryLock(long, TimeUnit) tryLock(0, TimeUnit.SECONDS)}
* which is almost equivalent (it also detects interruption).
*
* <p>If the current thread already holds this lock then the hold
--- a/jdk/src/java.base/share/classes/java/util/concurrent/locks/ReentrantReadWriteLock.java Mon Jul 24 11:54:57 2017 +0530
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/locks/ReentrantReadWriteLock.java Tue Jul 25 14:07:37 2017 -0700
@@ -797,7 +797,7 @@
* can be useful in certain circumstances, even though it
* breaks fairness. If you want to honor the fairness setting
* for this lock, then use {@link #tryLock(long, TimeUnit)
- * tryLock(0, TimeUnit.SECONDS) } which is almost equivalent
+ * tryLock(0, TimeUnit.SECONDS)} which is almost equivalent
* (it also detects interruption).
*
* <p>If the write lock is held by another thread then
@@ -1029,7 +1029,7 @@
* behavior can be useful in certain circumstances, even
* though it breaks fairness. If you want to honor the
* fairness setting for this lock, then use {@link
- * #tryLock(long, TimeUnit) tryLock(0, TimeUnit.SECONDS) }
+ * #tryLock(long, TimeUnit) tryLock(0, TimeUnit.SECONDS)}
* which is almost equivalent (it also detects interruption).
*
* <p>If the current thread already holds this lock then the
--- a/jdk/src/java.base/share/classes/sun/security/util/IOUtils.java Mon Jul 24 11:54:57 2017 +0530
+++ b/jdk/src/java.base/share/classes/sun/security/util/IOUtils.java Tue Jul 25 14:07:37 2017 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2017 Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -40,17 +40,18 @@
* Read up to <code>length</code> of bytes from <code>in</code>
* until EOF is detected.
* @param is input stream, must not be null
- * @param length number of bytes to read, -1 or Integer.MAX_VALUE means
- * read as much as possible
+ * @param length number of bytes to read
* @param readAll if true, an EOFException will be thrown if not enough
- * bytes are read. Ignored when length is -1 or Integer.MAX_VALUE
+ * bytes are read.
* @return bytes read
* @throws IOException Any IO error or a premature EOF is detected
*/
public static byte[] readFully(InputStream is, int length, boolean readAll)
throws IOException {
+ if (length < 0) {
+ throw new IOException("Invalid length");
+ }
byte[] output = {};
- if (length == -1) length = Integer.MAX_VALUE;
int pos = 0;
while (pos < length) {
int bytesToRead;
@@ -64,7 +65,7 @@
}
int cc = is.read(output, pos, bytesToRead);
if (cc < 0) {
- if (readAll && length != Integer.MAX_VALUE) {
+ if (readAll) {
throw new EOFException("Detect premature EOF");
} else {
if (output.length != pos) {
--- a/jdk/src/java.management/share/classes/javax/management/remote/JMXConnectorFactory.java Mon Jul 24 11:54:57 2017 +0530
+++ b/jdk/src/java.management/share/classes/javax/management/remote/JMXConnectorFactory.java Tue Jul 25 14:07:37 2017 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -137,7 +137,7 @@
* <code>MalformedURLException</code> if there is none. An
* implementation may choose to find providers by other means. For
* example, it may support <a
- * href="{@docRoot}/../java/util/ServiceLoader.html#developing-service-providers">service providers</a>,
+ * href="{@docRoot}/java/util/ServiceLoader.html#developing-service-providers">service providers</a>,
* where the service interface is <code>JMXConnectorProvider</code>.</p>
*
* <p>Every implementation must support the RMI connector protocol with
--- a/jdk/src/java.management/share/classes/javax/management/remote/JMXConnectorServerFactory.java Mon Jul 24 11:54:57 2017 +0530
+++ b/jdk/src/java.management/share/classes/javax/management/remote/JMXConnectorServerFactory.java Tue Jul 25 14:07:37 2017 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -128,7 +128,7 @@
* <code>MalformedURLException</code> if there is none. An
* implementation may choose to find providers by other means. For
* example, it may support <a
- * href="{@docRoot}/../java/util/ServiceLoader.html#developing-service-providers">service providers</a>,
+ * href="{@docRoot}/java/util/ServiceLoader.html#developing-service-providers">service providers</a>,
* where the service interface is <code>JMXConnectorServerProvider</code>.</p>
*
* <p>Every implementation must support the RMI connector protocol with
--- a/jdk/src/java.rmi/share/classes/module-info.java Mon Jul 24 11:54:57 2017 +0530
+++ b/jdk/src/java.rmi/share/classes/module-info.java Tue Jul 25 14:07:37 2017 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -31,7 +31,6 @@
* object registry, and the <em>{@index rmid rmid tool}</em> tool to start
* the activation system daemon.
*
- * <p>
* <dl style="font-family:'DejaVu Sans', Arial, Helvetica, sans serif">
* <dt class="simpleTagLabel">Tool Guides:</dt>
* <dd> {@extLink rmiregistry_tool_reference rmiregistry},
--- a/jdk/test/java/util/Collection/IteratorMicroBenchmark.java Mon Jul 24 11:54:57 2017 +0530
+++ b/jdk/test/java/util/Collection/IteratorMicroBenchmark.java Tue Jul 25 14:07:37 2017 -0700
@@ -56,6 +56,7 @@
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.LongAdder;
import java.util.regex.Pattern;
/**
@@ -391,16 +392,53 @@
for (Integer o : x.toArray(empty))
sum[0] += o;
check.sum(sum[0]);}}},
+ new Job(klazz + " stream().forEach") {
+ public void work() throws Throwable {
+ int[] sum = new int[1];
+ for (int i = 0; i < iterations; i++) {
+ sum[0] = 0;
+ x.stream().forEach(n -> sum[0] += n);
+ check.sum(sum[0]);}}},
+ new Job(klazz + " stream().mapToInt") {
+ public void work() throws Throwable {
+ for (int i = 0; i < iterations; i++) {
+ check.sum(x.stream().mapToInt(e -> e).sum());}}},
new Job(klazz + " stream().collect") {
public void work() throws Throwable {
for (int i = 0; i < iterations; i++) {
check.sum(x.stream()
.collect(summingInt(e -> e)));}}},
+ new Job(klazz + " stream()::iterator") {
+ public void work() throws Throwable {
+ int[] sum = new int[1];
+ for (int i = 0; i < iterations; i++) {
+ sum[0] = 0;
+ for (Integer o : (Iterable<Integer>) x.stream()::iterator)
+ sum[0] += o;
+ check.sum(sum[0]);}}},
+ new Job(klazz + " parallelStream().forEach") {
+ public void work() throws Throwable {
+ for (int i = 0; i < iterations; i++) {
+ LongAdder sum = new LongAdder();
+ x.parallelStream().forEach(n -> sum.add(n));
+ check.sum((int) sum.sum());}}},
+ new Job(klazz + " parallelStream().mapToInt") {
+ public void work() throws Throwable {
+ for (int i = 0; i < iterations; i++) {
+ check.sum(x.parallelStream().mapToInt(e -> e).sum());}}},
new Job(klazz + " parallelStream().collect") {
public void work() throws Throwable {
for (int i = 0; i < iterations; i++) {
check.sum(x.parallelStream()
- .collect(summingInt(e -> e)));}}});
+ .collect(summingInt(e -> e)));}}},
+ new Job(klazz + " parallelStream()::iterator") {
+ public void work() throws Throwable {
+ int[] sum = new int[1];
+ for (int i = 0; i < iterations; i++) {
+ sum[0] = 0;
+ for (Integer o : (Iterable<Integer>) x.parallelStream()::iterator)
+ sum[0] += o;
+ check.sum(sum[0]);}}});
}
List<Job> dequeJobs(Deque<Integer> x) {
--- a/jdk/test/java/util/concurrent/tck/AbstractExecutorServiceTest.java Mon Jul 24 11:54:57 2017 +0530
+++ b/jdk/test/java/util/concurrent/tck/AbstractExecutorServiceTest.java Tue Jul 25 14:07:37 2017 -0700
@@ -38,6 +38,7 @@
import java.security.PrivilegedAction;
import java.security.PrivilegedExceptionAction;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.AbstractExecutorService;
@@ -192,25 +193,13 @@
}
/**
- * execute(null runnable) throws NPE
+ * Submitting null tasks throws NullPointerException
*/
- public void testExecuteNullRunnable() {
- ExecutorService e = new DirectExecutorService();
- try {
- e.submit((Runnable) null);
- shouldThrow();
- } catch (NullPointerException success) {}
- }
-
- /**
- * submit(null callable) throws NPE
- */
- public void testSubmitNullCallable() {
- ExecutorService e = new DirectExecutorService();
- try {
- e.submit((Callable) null);
- shouldThrow();
- } catch (NullPointerException success) {}
+ public void testNullTaskSubmission() {
+ final ExecutorService e = new DirectExecutorService();
+ try (PoolCleaner cleaner = cleaner(e)) {
+ assertNullTaskSubmissionThrowsNullPointerException(e);
+ }
}
/**
@@ -276,13 +265,15 @@
}
/**
- * invokeAny(empty collection) throws IAE
+ * invokeAny(empty collection) throws IllegalArgumentException
*/
public void testInvokeAny2() throws Exception {
final ExecutorService e = new DirectExecutorService();
+ final Collection<Callable<String>> emptyCollection
+ = Collections.emptyList();
try (PoolCleaner cleaner = cleaner(e)) {
try {
- e.invokeAny(new ArrayList<Callable<String>>());
+ e.invokeAny(emptyCollection);
shouldThrow();
} catch (IllegalArgumentException success) {}
}
@@ -350,12 +341,14 @@
}
/**
- * invokeAll(empty collection) returns empty collection
+ * invokeAll(empty collection) returns empty list
*/
public void testInvokeAll2() throws InterruptedException {
final ExecutorService e = new DirectExecutorService();
+ final Collection<Callable<String>> emptyCollection
+ = Collections.emptyList();
try (PoolCleaner cleaner = cleaner(e)) {
- List<Future<String>> r = e.invokeAll(new ArrayList<Callable<String>>());
+ List<Future<String>> r = e.invokeAll(emptyCollection);
assertTrue(r.isEmpty());
}
}
@@ -418,14 +411,14 @@
final ExecutorService e = new DirectExecutorService();
try (PoolCleaner cleaner = cleaner(e)) {
try {
- e.invokeAny(null, MEDIUM_DELAY_MS, MILLISECONDS);
+ e.invokeAny(null, randomTimeout(), randomTimeUnit());
shouldThrow();
} catch (NullPointerException success) {}
}
}
/**
- * timed invokeAny(null time unit) throws NPE
+ * timed invokeAny(null time unit) throws NullPointerException
*/
public void testTimedInvokeAnyNullTimeUnit() throws Exception {
final ExecutorService e = new DirectExecutorService();
@@ -433,21 +426,22 @@
List<Callable<String>> l = new ArrayList<>();
l.add(new StringTask());
try {
- e.invokeAny(l, MEDIUM_DELAY_MS, null);
+ e.invokeAny(l, randomTimeout(), null);
shouldThrow();
} catch (NullPointerException success) {}
}
}
/**
- * timed invokeAny(empty collection) throws IAE
+ * timed invokeAny(empty collection) throws IllegalArgumentException
*/
public void testTimedInvokeAny2() throws Exception {
final ExecutorService e = new DirectExecutorService();
+ final Collection<Callable<String>> emptyCollection
+ = Collections.emptyList();
try (PoolCleaner cleaner = cleaner(e)) {
try {
- e.invokeAny(new ArrayList<Callable<String>>(),
- MEDIUM_DELAY_MS, MILLISECONDS);
+ e.invokeAny(emptyCollection, randomTimeout(), randomTimeUnit());
shouldThrow();
} catch (IllegalArgumentException success) {}
}
@@ -464,7 +458,7 @@
public Long call() { throw new ArithmeticException(); }});
l.add(null);
try {
- e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
+ e.invokeAny(l, randomTimeout(), randomTimeUnit());
shouldThrow();
} catch (NullPointerException success) {}
}
@@ -506,13 +500,13 @@
}
/**
- * timed invokeAll(null) throws NPE
+ * timed invokeAll(null) throws NullPointerException
*/
public void testTimedInvokeAll1() throws InterruptedException {
final ExecutorService e = new DirectExecutorService();
try (PoolCleaner cleaner = cleaner(e)) {
try {
- e.invokeAll(null, MEDIUM_DELAY_MS, MILLISECONDS);
+ e.invokeAll(null, randomTimeout(), randomTimeUnit());
shouldThrow();
} catch (NullPointerException success) {}
}
@@ -527,25 +521,28 @@
List<Callable<String>> l = new ArrayList<>();
l.add(new StringTask());
try {
- e.invokeAll(l, MEDIUM_DELAY_MS, null);
+ e.invokeAll(l, randomTimeout(), null);
shouldThrow();
} catch (NullPointerException success) {}
}
}
/**
- * timed invokeAll(empty collection) returns empty collection
+ * timed invokeAll(empty collection) returns empty list
*/
public void testTimedInvokeAll2() throws InterruptedException {
final ExecutorService e = new DirectExecutorService();
+ final Collection<Callable<String>> emptyCollection
+ = Collections.emptyList();
try (PoolCleaner cleaner = cleaner(e)) {
- List<Future<String>> r = e.invokeAll(new ArrayList<Callable<String>>(), MEDIUM_DELAY_MS, MILLISECONDS);
+ List<Future<String>> r =
+ e.invokeAll(emptyCollection, randomTimeout(), randomTimeUnit());
assertTrue(r.isEmpty());
}
}
/**
- * timed invokeAll(c) throws NPE if c has null elements
+ * timed invokeAll(c) throws NullPointerException if c has null elements
*/
public void testTimedInvokeAll3() throws InterruptedException {
final ExecutorService e = new DirectExecutorService();
@@ -554,7 +551,7 @@
l.add(new StringTask());
l.add(null);
try {
- e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
+ e.invokeAll(l, randomTimeout(), randomTimeUnit());
shouldThrow();
} catch (NullPointerException success) {}
}
--- a/jdk/test/java/util/concurrent/tck/AbstractQueueTest.java Mon Jul 24 11:54:57 2017 +0530
+++ b/jdk/test/java/util/concurrent/tck/AbstractQueueTest.java Tue Jul 25 14:07:37 2017 -0700
@@ -80,7 +80,7 @@
}
/**
- * add throws ISE true if offer fails
+ * add throws IllegalStateException true if offer fails
*/
public void testAddF() {
Fail q = new Fail();
@@ -91,7 +91,7 @@
}
/**
- * add throws NPE if offer does
+ * add throws NullPointerException if offer does
*/
public void testAddNPE() {
Succeed q = new Succeed();
@@ -140,7 +140,7 @@
}
/**
- * addAll(null) throws NPE
+ * addAll(null) throws NullPointerException
*/
public void testAddAll1() {
Succeed q = new Succeed();
@@ -151,7 +151,7 @@
}
/**
- * addAll(this) throws IAE
+ * addAll(this) throws IllegalArgumentException
*/
public void testAddAllSelf() {
Succeed q = new Succeed();
@@ -162,7 +162,7 @@
}
/**
- * addAll of a collection with null elements throws NPE
+ * addAll of a collection with null elements throws NullPointerException
*/
public void testAddAll2() {
Succeed q = new Succeed();
@@ -189,7 +189,7 @@
}
/**
- * addAll throws ISE if an add fails
+ * addAll throws IllegalStateException if an add fails
*/
public void testAddAll4() {
Fail q = new Fail();
--- a/jdk/test/java/util/concurrent/tck/AbstractQueuedLongSynchronizerTest.java Mon Jul 24 11:54:57 2017 +0530
+++ b/jdk/test/java/util/concurrent/tck/AbstractQueuedLongSynchronizerTest.java Tue Jul 25 14:07:37 2017 -0700
@@ -46,6 +46,7 @@
import junit.framework.Test;
import junit.framework.TestSuite;
+@SuppressWarnings("WaitNotInLoop") // we implement spurious-wakeup freedom
public class AbstractQueuedLongSynchronizerTest extends JSR166TestCase {
public static void main(String[] args) {
main(suite(), args);
@@ -992,30 +993,30 @@
*/
public void testAwaitUninterruptibly() {
final Mutex sync = new Mutex();
- final ConditionObject c = sync.newCondition();
+ final ConditionObject condition = sync.newCondition();
final BooleanLatch pleaseInterrupt = new BooleanLatch();
Thread t = newStartedThread(new CheckedRunnable() {
public void realRun() {
sync.acquire();
assertTrue(pleaseInterrupt.releaseShared(0));
- c.awaitUninterruptibly();
+ condition.awaitUninterruptibly();
assertTrue(Thread.interrupted());
- assertHasWaitersLocked(sync, c, NO_THREADS);
+ assertHasWaitersLocked(sync, condition, NO_THREADS);
sync.release();
}});
pleaseInterrupt.acquireShared(0);
sync.acquire();
- assertHasWaitersLocked(sync, c, t);
+ assertHasWaitersLocked(sync, condition, t);
sync.release();
t.interrupt();
- assertHasWaitersUnlocked(sync, c, t);
- assertThreadStaysAlive(t);
+ assertHasWaitersUnlocked(sync, condition, t);
+ assertThreadBlocks(t, Thread.State.WAITING);
sync.acquire();
- assertHasWaitersLocked(sync, c, t);
+ assertHasWaitersLocked(sync, condition, t);
assertHasExclusiveQueuedThreads(sync, NO_THREADS);
- c.signal();
- assertHasWaitersLocked(sync, c, NO_THREADS);
+ condition.signal();
+ assertHasWaitersLocked(sync, condition, NO_THREADS);
assertHasExclusiveQueuedThreads(sync, t);
sync.release();
awaitTermination(t);
@@ -1158,7 +1159,7 @@
waitForQueuedThread(l, t);
assertFalse(l.isSignalled());
- assertThreadStaysAlive(t);
+ assertThreadBlocks(t, Thread.State.WAITING);
assertHasSharedQueuedThreads(l, t);
assertTrue(l.releaseShared(0));
assertTrue(l.isSignalled());
@@ -1183,7 +1184,7 @@
waitForQueuedThread(l, t);
assertFalse(l.isSignalled());
- assertThreadStaysAlive(t);
+ assertThreadBlocks(t, Thread.State.TIMED_WAITING);
assertTrue(l.releaseShared(0));
assertTrue(l.isSignalled());
awaitTermination(t);
--- a/jdk/test/java/util/concurrent/tck/AbstractQueuedSynchronizerTest.java Mon Jul 24 11:54:57 2017 +0530
+++ b/jdk/test/java/util/concurrent/tck/AbstractQueuedSynchronizerTest.java Tue Jul 25 14:07:37 2017 -0700
@@ -46,6 +46,7 @@
import junit.framework.Test;
import junit.framework.TestSuite;
+@SuppressWarnings("WaitNotInLoop") // we implement spurious-wakeup freedom
public class AbstractQueuedSynchronizerTest extends JSR166TestCase {
public static void main(String[] args) {
main(suite(), args);
@@ -995,30 +996,30 @@
*/
public void testAwaitUninterruptibly() {
final Mutex sync = new Mutex();
- final ConditionObject c = sync.newCondition();
+ final ConditionObject condition = sync.newCondition();
final BooleanLatch pleaseInterrupt = new BooleanLatch();
Thread t = newStartedThread(new CheckedRunnable() {
public void realRun() {
sync.acquire();
assertTrue(pleaseInterrupt.releaseShared(0));
- c.awaitUninterruptibly();
+ condition.awaitUninterruptibly();
assertTrue(Thread.interrupted());
- assertHasWaitersLocked(sync, c, NO_THREADS);
+ assertHasWaitersLocked(sync, condition, NO_THREADS);
sync.release();
}});
pleaseInterrupt.acquireShared(0);
sync.acquire();
- assertHasWaitersLocked(sync, c, t);
+ assertHasWaitersLocked(sync, condition, t);
sync.release();
t.interrupt();
- assertHasWaitersUnlocked(sync, c, t);
- assertThreadStaysAlive(t);
+ assertHasWaitersUnlocked(sync, condition, t);
+ assertThreadBlocks(t, Thread.State.WAITING);
sync.acquire();
- assertHasWaitersLocked(sync, c, t);
+ assertHasWaitersLocked(sync, condition, t);
assertHasExclusiveQueuedThreads(sync, NO_THREADS);
- c.signal();
- assertHasWaitersLocked(sync, c, NO_THREADS);
+ condition.signal();
+ assertHasWaitersLocked(sync, condition, NO_THREADS);
assertHasExclusiveQueuedThreads(sync, t);
sync.release();
awaitTermination(t);
@@ -1161,7 +1162,7 @@
waitForQueuedThread(l, t);
assertFalse(l.isSignalled());
- assertThreadStaysAlive(t);
+ assertThreadBlocks(t, Thread.State.WAITING);
assertHasSharedQueuedThreads(l, t);
assertTrue(l.releaseShared(0));
assertTrue(l.isSignalled());
@@ -1186,7 +1187,7 @@
waitForQueuedThread(l, t);
assertFalse(l.isSignalled());
- assertThreadStaysAlive(t);
+ assertThreadBlocks(t, Thread.State.TIMED_WAITING);
assertTrue(l.releaseShared(0));
assertTrue(l.isSignalled());
awaitTermination(t);
--- a/jdk/test/java/util/concurrent/tck/ArrayBlockingQueueTest.java Mon Jul 24 11:54:57 2017 +0530
+++ b/jdk/test/java/util/concurrent/tck/ArrayBlockingQueueTest.java Tue Jul 25 14:07:37 2017 -0700
@@ -130,7 +130,7 @@
}
/**
- * Constructor throws IAE if capacity argument nonpositive
+ * Constructor throws IllegalArgumentException if capacity argument nonpositive
*/
public void testConstructor_nonPositiveCapacity() {
for (int i : new int[] { 0, -1, Integer.MIN_VALUE }) {
@@ -183,7 +183,7 @@
}
/**
- * Initializing from too large collection throws IAE
+ * Initializing from too large collection throws IllegalArgumentException
*/
public void testConstructor_collectionTooLarge() {
// just barely fits - succeeds
@@ -254,7 +254,7 @@
}
/**
- * add succeeds if not full; throws ISE if full
+ * add succeeds if not full; throws IllegalStateException if full
*/
public void testAdd() {
ArrayBlockingQueue q = new ArrayBlockingQueue(SIZE);
@@ -267,7 +267,7 @@
}
/**
- * addAll(this) throws IAE
+ * addAll(this) throws IllegalArgumentException
*/
public void testAddAllSelf() {
ArrayBlockingQueue q = populatedQueue(SIZE);
@@ -293,7 +293,7 @@
}
/**
- * addAll throws ISE if not enough room
+ * addAll throws IllegalStateException if not enough room
*/
public void testAddAll_insufficientSpace() {
int size = ThreadLocalRandom.current().nextInt(1, SIZE);
@@ -367,7 +367,7 @@
}});
await(pleaseInterrupt);
- assertThreadStaysAlive(t);
+ assertThreadBlocks(t, Thread.State.WAITING);
t.interrupt();
awaitTermination(t);
assertEquals(SIZE, q.size());
@@ -389,6 +389,13 @@
pleaseTake.countDown();
q.put(86);
+ Thread.currentThread().interrupt();
+ try {
+ q.put(99);
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+
pleaseInterrupt.countDown();
try {
q.put(99);
@@ -402,7 +409,7 @@
assertEquals(0, q.take());
await(pleaseInterrupt);
- assertThreadStaysAlive(t);
+ assertThreadBlocks(t, Thread.State.WAITING);
t.interrupt();
awaitTermination(t);
assertEquals(0, q.remainingCapacity());
@@ -411,7 +418,7 @@
/**
* timed offer times out if full and elements not taken
*/
- public void testTimedOffer() throws InterruptedException {
+ public void testTimedOffer() {
final ArrayBlockingQueue q = new ArrayBlockingQueue(2);
final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
Thread t = newStartedThread(new CheckedRunnable() {
@@ -421,15 +428,24 @@
long startTime = System.nanoTime();
assertFalse(q.offer(new Object(), timeoutMillis(), MILLISECONDS));
assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+
+ Thread.currentThread().interrupt();
+ try {
+ q.offer(new Object(), 2 * LONG_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+
pleaseInterrupt.countDown();
try {
q.offer(new Object(), 2 * LONG_DELAY_MS, MILLISECONDS);
shouldThrow();
} catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
}});
await(pleaseInterrupt);
- assertThreadStaysAlive(t);
+ assertThreadBlocks(t, Thread.State.TIMED_WAITING);
t.interrupt();
awaitTermination(t);
}
@@ -452,9 +468,7 @@
final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
Thread t = newStartedThread(new CheckedRunnable() {
public void realRun() throws InterruptedException {
- for (int i = 0; i < SIZE; ++i) {
- assertEquals(i, q.take());
- }
+ for (int i = 0; i < SIZE; i++) assertEquals(i, q.take());
Thread.currentThread().interrupt();
try {
@@ -472,7 +486,7 @@
}});
await(pleaseInterrupt);
- assertThreadStaysAlive(t);
+ assertThreadBlocks(t, Thread.State.WAITING);
t.interrupt();
awaitTermination(t);
}
@@ -522,24 +536,32 @@
*/
public void testInterruptedTimedPoll() throws InterruptedException {
final BlockingQueue<Integer> q = populatedQueue(SIZE);
- final CountDownLatch aboutToWait = new CountDownLatch(1);
+ final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
Thread t = newStartedThread(new CheckedRunnable() {
public void realRun() throws InterruptedException {
long startTime = System.nanoTime();
- for (int i = 0; i < SIZE; ++i) {
+ for (int i = 0; i < SIZE; i++)
assertEquals(i, (int) q.poll(LONG_DELAY_MS, MILLISECONDS));
- }
- aboutToWait.countDown();
+
+ Thread.currentThread().interrupt();
try {
q.poll(LONG_DELAY_MS, MILLISECONDS);
shouldThrow();
- } catch (InterruptedException success) {
- assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
- }
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+
+ pleaseInterrupt.countDown();
+ try {
+ q.poll(LONG_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+
+ assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
}});
- await(aboutToWait);
- waitForThreadToEnterWaitState(t);
+ await(pleaseInterrupt);
+ assertThreadBlocks(t, Thread.State.TIMED_WAITING);
t.interrupt();
awaitTermination(t);
checkEmpty(q);
--- a/jdk/test/java/util/concurrent/tck/BlockingQueueTest.java Mon Jul 24 11:54:57 2017 +0530
+++ b/jdk/test/java/util/concurrent/tck/BlockingQueueTest.java Tue Jul 25 14:07:37 2017 -0700
@@ -133,7 +133,7 @@
}
/**
- * put(null) throws NullPointerException
+ * addAll(null) throws NullPointerException
*/
public void testAddAllNull() throws InterruptedException {
final Collection q = emptyCollection();
@@ -272,7 +272,7 @@
assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
barrier.await();
- assertThreadStaysAlive(t);
+ assertThreadBlocks(t, Thread.State.TIMED_WAITING);
t.interrupt();
awaitTermination(t);
}
@@ -294,7 +294,7 @@
}});
await(threadStarted);
- assertThreadStaysAlive(t);
+ assertThreadBlocks(t, Thread.State.WAITING);
t.interrupt();
awaitTermination(t);
}
@@ -335,7 +335,7 @@
}});
await(threadStarted);
- assertThreadStaysAlive(t);
+ assertThreadBlocks(t, Thread.State.TIMED_WAITING);
t.interrupt();
awaitTermination(t);
}
--- a/jdk/test/java/util/concurrent/tck/Collection8Test.java Mon Jul 24 11:54:57 2017 +0530
+++ b/jdk/test/java/util/concurrent/tck/Collection8Test.java Tue Jul 25 14:07:37 2017 -0700
@@ -167,12 +167,12 @@
}
if (c instanceof BlockingQueue) {
BlockingQueue q = (BlockingQueue) c;
- assertNull(q.poll(0L, MILLISECONDS));
+ assertNull(q.poll(randomExpiredTimeout(), randomTimeUnit()));
}
if (c instanceof BlockingDeque) {
BlockingDeque q = (BlockingDeque) c;
- assertNull(q.pollFirst(0L, MILLISECONDS));
- assertNull(q.pollLast(0L, MILLISECONDS));
+ assertNull(q.pollFirst(randomExpiredTimeout(), randomTimeUnit()));
+ assertNull(q.pollLast(randomExpiredTimeout(), randomTimeUnit()));
}
}
--- a/jdk/test/java/util/concurrent/tck/CompletableFutureTest.java Mon Jul 24 11:54:57 2017 +0530
+++ b/jdk/test/java/util/concurrent/tck/CompletableFutureTest.java Tue Jul 25 14:07:37 2017 -0700
@@ -91,7 +91,7 @@
assertNull(f.getNow(null));
} catch (Throwable fail) { threadUnexpectedException(fail); }
try {
- f.get(0L, SECONDS);
+ f.get(randomExpiredTimeout(), randomTimeUnit());
shouldThrow();
}
catch (TimeoutException success) {}
@@ -103,11 +103,7 @@
try {
assertEquals(value, f.join());
- } catch (Throwable fail) { threadUnexpectedException(fail); }
- try {
assertEquals(value, f.getNow(null));
- } catch (Throwable fail) { threadUnexpectedException(fail); }
- try {
assertEquals(value, f.get());
} catch (Throwable fail) { threadUnexpectedException(fail); }
assertTrue(f.isDone());
@@ -1269,6 +1265,7 @@
r.assertInvoked();
}}
+ @SuppressWarnings("FutureReturnValueIgnored")
public void testRunAsync_rejectingExecutor() {
CountingRejectingExecutor e = new CountingRejectingExecutor();
try {
@@ -1315,6 +1312,7 @@
r.assertInvoked();
}}
+ @SuppressWarnings("FutureReturnValueIgnored")
public void testSupplyAsync_rejectingExecutor() {
CountingRejectingExecutor e = new CountingRejectingExecutor();
try {
@@ -3265,6 +3263,7 @@
/**
* Completion methods throw NullPointerException with null arguments
*/
+ @SuppressWarnings("FutureReturnValueIgnored")
public void testNPE() {
CompletableFuture<Integer> f = new CompletableFuture<>();
CompletableFuture<Integer> g = new CompletableFuture<>();
@@ -4326,6 +4325,7 @@
}
/** Test long recursive chains of CompletableFutures with cascading completions */
+ @SuppressWarnings("FutureReturnValueIgnored")
public void testRecursiveChains() throws Throwable {
for (ExecutionMode m : ExecutionMode.values())
for (boolean addDeadEnds : new boolean[] { true, false })
@@ -4350,6 +4350,7 @@
* A single CompletableFuture with many dependents.
* A demo of scalability - runtime is O(n).
*/
+ @SuppressWarnings("FutureReturnValueIgnored")
public void testManyDependents() throws Throwable {
final int n = expensiveTests ? 1_000_000 : 10;
final CompletableFuture<Void> head = new CompletableFuture<>();
@@ -4379,6 +4380,7 @@
}
/** ant -Dvmoptions=-Xmx8m -Djsr166.expensiveTests=true -Djsr166.tckTestClass=CompletableFutureTest tck */
+ @SuppressWarnings("FutureReturnValueIgnored")
public void testCoCompletionGarbageRetention() throws Throwable {
final int n = expensiveTests ? 1_000_000 : 10;
final CompletableFuture<Integer> incomplete = new CompletableFuture<>();
--- a/jdk/test/java/util/concurrent/tck/ConcurrentLinkedDequeTest.java Mon Jul 24 11:54:57 2017 +0530
+++ b/jdk/test/java/util/concurrent/tck/ConcurrentLinkedDequeTest.java Tue Jul 25 14:07:37 2017 -0700
@@ -339,7 +339,7 @@
}
/**
- * addAll(this) throws IAE
+ * addAll(this) throws IllegalArgumentException
*/
public void testAddAllSelf() {
ConcurrentLinkedDeque q = populatedDeque(SIZE);
--- a/jdk/test/java/util/concurrent/tck/ConcurrentLinkedQueueTest.java Mon Jul 24 11:54:57 2017 +0530
+++ b/jdk/test/java/util/concurrent/tck/ConcurrentLinkedQueueTest.java Tue Jul 25 14:07:37 2017 -0700
@@ -199,7 +199,7 @@
}
/**
- * addAll(null) throws NPE
+ * addAll(null) throws NullPointerException
*/
public void testAddAll1() {
ConcurrentLinkedQueue q = new ConcurrentLinkedQueue();
@@ -210,7 +210,7 @@
}
/**
- * addAll(this) throws IAE
+ * addAll(this) throws IllegalArgumentException
*/
public void testAddAllSelf() {
ConcurrentLinkedQueue q = populatedQueue(SIZE);
@@ -221,7 +221,7 @@
}
/**
- * addAll of a collection with null elements throws NPE
+ * addAll of a collection with null elements throws NullPointerException
*/
public void testAddAll2() {
ConcurrentLinkedQueue q = new ConcurrentLinkedQueue();
--- a/jdk/test/java/util/concurrent/tck/CountDownLatchTest.java Mon Jul 24 11:54:57 2017 +0530
+++ b/jdk/test/java/util/concurrent/tck/CountDownLatchTest.java Tue Jul 25 14:07:37 2017 -0700
@@ -49,7 +49,7 @@
}
/**
- * negative constructor argument throws IAE
+ * negative constructor argument throws IllegalArgumentException
*/
public void testConstructor() {
try {
@@ -99,7 +99,7 @@
assertEquals(2, l.getCount());
l.countDown();
assertEquals(1, l.getCount());
- assertThreadStaysAlive(t);
+ assertThreadBlocks(t, Thread.State.WAITING);
l.countDown();
assertEquals(0, l.getCount());
awaitTermination(t);
@@ -124,14 +124,14 @@
assertEquals(2, l.getCount());
l.countDown();
assertEquals(1, l.getCount());
- assertThreadStaysAlive(t);
+ assertThreadBlocks(t, Thread.State.TIMED_WAITING);
l.countDown();
assertEquals(0, l.getCount());
awaitTermination(t);
}
/**
- * await throws IE if interrupted before counted down
+ * await throws InterruptedException if interrupted before counted down
*/
public void testAwait_Interruptible() {
final CountDownLatch l = new CountDownLatch(1);
@@ -156,13 +156,13 @@
}});
await(pleaseInterrupt);
- assertThreadStaysAlive(t);
+ assertThreadBlocks(t, Thread.State.WAITING);
t.interrupt();
awaitTermination(t);
}
/**
- * timed await throws IE if interrupted before counted down
+ * timed await throws InterruptedException if interrupted before counted down
*/
public void testTimedAwait_Interruptible() {
final CountDownLatch l = new CountDownLatch(1);
@@ -187,7 +187,7 @@
}});
await(pleaseInterrupt);
- assertThreadStaysAlive(t);
+ assertThreadBlocks(t, Thread.State.TIMED_WAITING);
t.interrupt();
awaitTermination(t);
}
--- a/jdk/test/java/util/concurrent/tck/CountedCompleterTest.java Mon Jul 24 11:54:57 2017 +0530
+++ b/jdk/test/java/util/concurrent/tck/CountedCompleterTest.java Tue Jul 25 14:07:37 2017 -0700
@@ -32,7 +32,6 @@
*/
import static java.util.concurrent.TimeUnit.MILLISECONDS;
-import static java.util.concurrent.TimeUnit.SECONDS;
import java.util.HashSet;
import java.util.concurrent.CancellationException;
@@ -104,7 +103,7 @@
assertNull(a.getRawResult());
try {
- a.get(0L, SECONDS);
+ a.get(randomExpiredTimeout(), randomTimeUnit());
shouldThrow();
} catch (TimeoutException success) {
} catch (Throwable fail) { threadUnexpectedException(fail); }
@@ -122,7 +121,7 @@
Thread.currentThread().interrupt();
long startTime = System.nanoTime();
assertNull(a.join());
- assertTrue(millisElapsedSince(startTime) < SMALL_DELAY_MS);
+ assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
Thread.interrupted();
}
@@ -130,7 +129,7 @@
Thread.currentThread().interrupt();
long startTime = System.nanoTime();
a.quietlyJoin(); // should be no-op
- assertTrue(millisElapsedSince(startTime) < SMALL_DELAY_MS);
+ assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
Thread.interrupted();
}
@@ -138,9 +137,7 @@
assertFalse(a.cancel(true));
try {
assertNull(a.get());
- } catch (Throwable fail) { threadUnexpectedException(fail); }
- try {
- assertNull(a.get(5L, SECONDS));
+ assertNull(a.get(randomTimeout(), randomTimeUnit()));
} catch (Throwable fail) { threadUnexpectedException(fail); }
}
@@ -165,7 +162,7 @@
{
long startTime = System.nanoTime();
a.quietlyJoin(); // should be no-op
- assertTrue(millisElapsedSince(startTime) < SMALL_DELAY_MS);
+ assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
}
try {
@@ -175,7 +172,7 @@
} catch (Throwable fail) { threadUnexpectedException(fail); }
try {
- a.get(5L, SECONDS);
+ a.get(randomTimeout(), randomTimeUnit());
shouldThrow();
} catch (CancellationException success) {
} catch (Throwable fail) { threadUnexpectedException(fail); }
@@ -203,7 +200,7 @@
{
long startTime = System.nanoTime();
a.quietlyJoin(); // should be no-op
- assertTrue(millisElapsedSince(startTime) < SMALL_DELAY_MS);
+ assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
}
try {
@@ -214,7 +211,7 @@
} catch (Throwable fail) { threadUnexpectedException(fail); }
try {
- a.get(5L, SECONDS);
+ a.get(randomTimeout(), randomTimeUnit());
shouldThrow();
} catch (ExecutionException success) {
assertSame(t.getClass(), success.getCause().getClass());
@@ -729,7 +726,7 @@
CCF f = new LCCF(8);
assertSame(f, f.fork());
try {
- f.get(5L, null);
+ f.get(randomTimeout(), null);
shouldThrow();
} catch (NullPointerException success) {}
}};
@@ -1451,7 +1448,7 @@
CCF f = new LCCF(8);
assertSame(f, f.fork());
try {
- f.get(5L, null);
+ f.get(randomTimeout(), null);
shouldThrow();
} catch (NullPointerException success) {}
}};
--- a/jdk/test/java/util/concurrent/tck/CyclicBarrierTest.java Mon Jul 24 11:54:57 2017 +0530
+++ b/jdk/test/java/util/concurrent/tck/CyclicBarrierTest.java Tue Jul 25 14:07:37 2017 -0700
@@ -66,7 +66,7 @@
}
/**
- * Creating with negative parties throws IAE
+ * Creating with negative parties throws IllegalArgumentException
*/
public void testConstructor1() {
try {
@@ -76,7 +76,8 @@
}
/**
- * Creating with negative parties and no action throws IAE
+ * Creating with negative parties and no action throws
+ * IllegalArgumentException
*/
public void testConstructor2() {
try {
--- a/jdk/test/java/util/concurrent/tck/DelayQueueTest.java Mon Jul 24 11:54:57 2017 +0530
+++ b/jdk/test/java/util/concurrent/tck/DelayQueueTest.java Tue Jul 25 14:07:37 2017 -0700
@@ -142,7 +142,7 @@
* Returns a new queue of given size containing consecutive
* PDelays 0 ... n - 1.
*/
- private DelayQueue<PDelay> populatedQueue(int n) {
+ private static DelayQueue<PDelay> populatedQueue(int n) {
DelayQueue<PDelay> q = new DelayQueue<>();
assertTrue(q.isEmpty());
for (int i = n - 1; i >= 0; i -= 2)
@@ -261,7 +261,7 @@
}
/**
- * addAll(this) throws IAE
+ * addAll(this) throws IllegalArgumentException
*/
public void testAddAllSelf() {
DelayQueue q = populatedQueue(SIZE);
@@ -365,9 +365,8 @@
final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
Thread t = newStartedThread(new CheckedRunnable() {
public void realRun() throws InterruptedException {
- for (int i = 0; i < SIZE; ++i) {
+ for (int i = 0; i < SIZE; i++)
assertEquals(new PDelay(i), ((PDelay)q.take()));
- }
Thread.currentThread().interrupt();
try {
@@ -385,7 +384,7 @@
}});
await(pleaseInterrupt);
- assertThreadStaysAlive(t);
+ assertThreadBlocks(t, Thread.State.WAITING);
t.interrupt();
awaitTermination(t);
}
@@ -438,10 +437,9 @@
Thread t = newStartedThread(new CheckedRunnable() {
public void realRun() throws InterruptedException {
long startTime = System.nanoTime();
- for (int i = 0; i < SIZE; ++i) {
+ for (int i = 0; i < SIZE; i++)
assertEquals(new PDelay(i),
((PDelay)q.poll(LONG_DELAY_MS, MILLISECONDS)));
- }
Thread.currentThread().interrupt();
try {
@@ -456,11 +454,12 @@
shouldThrow();
} catch (InterruptedException success) {}
assertFalse(Thread.interrupted());
+
assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
}});
await(pleaseInterrupt);
- assertThreadStaysAlive(t);
+ assertThreadBlocks(t, Thread.State.TIMED_WAITING);
t.interrupt();
awaitTermination(t);
checkEmpty(q);
@@ -741,7 +740,9 @@
public void testTimedPollDelayed() throws InterruptedException {
DelayQueue q = new DelayQueue();
q.add(new NanoDelay(LONG_DELAY_MS * 1000000L));
+ long startTime = System.nanoTime();
assertNull(q.poll(timeoutMillis(), MILLISECONDS));
+ assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
}
/**
--- a/jdk/test/java/util/concurrent/tck/DoubleAccumulatorTest.java Mon Jul 24 11:54:57 2017 +0530
+++ b/jdk/test/java/util/concurrent/tck/DoubleAccumulatorTest.java Tue Jul 25 14:07:37 2017 -0700
@@ -34,6 +34,7 @@
import java.util.concurrent.Executors;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Phaser;
+import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.atomic.DoubleAccumulator;
import junit.framework.Test;
@@ -48,135 +49,130 @@
}
/**
- * default constructed initializes to zero
+ * new instance initialized to supplied identity
*/
public void testConstructor() {
- DoubleAccumulator ai = new DoubleAccumulator(Double::max, 0.0);
- assertEquals(0.0, ai.get());
+ for (double identity : new double[] {
+ Double.NEGATIVE_INFINITY,
+ Double.POSITIVE_INFINITY,
+ Double.MIN_VALUE,
+ Double.MAX_VALUE,
+ 0.0,
+ })
+ assertEquals(identity,
+ new DoubleAccumulator(Double::max, identity).get());
}
/**
* accumulate accumulates given value to current, and get returns current value
*/
public void testAccumulateAndGet() {
- DoubleAccumulator ai = new DoubleAccumulator(Double::max, 0.0);
- ai.accumulate(2.0);
- assertEquals(2.0, ai.get());
- ai.accumulate(-4.0);
- assertEquals(2.0, ai.get());
- ai.accumulate(4.0);
- assertEquals(4.0, ai.get());
+ DoubleAccumulator acc = new DoubleAccumulator(Double::max, 0.0);
+ acc.accumulate(2.0);
+ assertEquals(2.0, acc.get());
+ acc.accumulate(-4.0);
+ assertEquals(2.0, acc.get());
+ acc.accumulate(4.0);
+ assertEquals(4.0, acc.get());
}
/**
* reset() causes subsequent get() to return zero
*/
public void testReset() {
- DoubleAccumulator ai = new DoubleAccumulator(Double::max, 0.0);
- ai.accumulate(2.0);
- assertEquals(2.0, ai.get());
- ai.reset();
- assertEquals(0.0, ai.get());
+ DoubleAccumulator acc = new DoubleAccumulator(Double::max, 0.0);
+ acc.accumulate(2.0);
+ assertEquals(2.0, acc.get());
+ acc.reset();
+ assertEquals(0.0, acc.get());
}
/**
* getThenReset() returns current value; subsequent get() returns zero
*/
public void testGetThenReset() {
- DoubleAccumulator ai = new DoubleAccumulator(Double::max, 0.0);
- ai.accumulate(2.0);
- assertEquals(2.0, ai.get());
- assertEquals(2.0, ai.getThenReset());
- assertEquals(0.0, ai.get());
+ DoubleAccumulator acc = new DoubleAccumulator(Double::max, 0.0);
+ acc.accumulate(2.0);
+ assertEquals(2.0, acc.get());
+ assertEquals(2.0, acc.getThenReset());
+ assertEquals(0.0, acc.get());
}
/**
* toString returns current value.
*/
public void testToString() {
- DoubleAccumulator ai = new DoubleAccumulator(Double::max, 0.0);
- assertEquals("0.0", ai.toString());
- ai.accumulate(1.0);
- assertEquals(Double.toString(1.0), ai.toString());
+ DoubleAccumulator acc = new DoubleAccumulator(Double::max, 0.0);
+ assertEquals("0.0", acc.toString());
+ acc.accumulate(1.0);
+ assertEquals(Double.toString(1.0), acc.toString());
}
/**
* intValue returns current value.
*/
public void testIntValue() {
- DoubleAccumulator ai = new DoubleAccumulator(Double::max, 0.0);
- assertEquals(0, ai.intValue());
- ai.accumulate(1.0);
- assertEquals(1, ai.intValue());
+ DoubleAccumulator acc = new DoubleAccumulator(Double::max, 0.0);
+ assertEquals(0, acc.intValue());
+ acc.accumulate(1.0);
+ assertEquals(1, acc.intValue());
}
/**
* longValue returns current value.
*/
public void testLongValue() {
- DoubleAccumulator ai = new DoubleAccumulator(Double::max, 0.0);
- assertEquals(0, ai.longValue());
- ai.accumulate(1.0);
- assertEquals(1, ai.longValue());
+ DoubleAccumulator acc = new DoubleAccumulator(Double::max, 0.0);
+ assertEquals(0, acc.longValue());
+ acc.accumulate(1.0);
+ assertEquals(1, acc.longValue());
}
/**
* floatValue returns current value.
*/
public void testFloatValue() {
- DoubleAccumulator ai = new DoubleAccumulator(Double::max, 0.0);
- assertEquals(0.0f, ai.floatValue());
- ai.accumulate(1.0);
- assertEquals(1.0f, ai.floatValue());
+ DoubleAccumulator acc = new DoubleAccumulator(Double::max, 0.0);
+ assertEquals(0.0f, acc.floatValue());
+ acc.accumulate(1.0);
+ assertEquals(1.0f, acc.floatValue());
}
/**
* doubleValue returns current value.
*/
public void testDoubleValue() {
- DoubleAccumulator ai = new DoubleAccumulator(Double::max, 0.0);
- assertEquals(0.0, ai.doubleValue());
- ai.accumulate(1.0);
- assertEquals(1.0, ai.doubleValue());
+ DoubleAccumulator acc = new DoubleAccumulator(Double::max, 0.0);
+ assertEquals(0.0, acc.doubleValue());
+ acc.accumulate(1.0);
+ assertEquals(1.0, acc.doubleValue());
}
/**
* accumulates by multiple threads produce correct result
*/
public void testAccumulateAndGetMT() {
- final int incs = 1000000;
- final int nthreads = 4;
- final ExecutorService pool = Executors.newCachedThreadPool();
- DoubleAccumulator a = new DoubleAccumulator(Double::max, 0.0);
- Phaser phaser = new Phaser(nthreads + 1);
- for (int i = 0; i < nthreads; ++i)
- pool.execute(new AccTask(a, phaser, incs));
- phaser.arriveAndAwaitAdvance();
- phaser.arriveAndAwaitAdvance();
- double expected = incs - 1;
- double result = a.get();
- assertEquals(expected, result);
- pool.shutdown();
- }
-
- static final class AccTask implements Runnable {
- final DoubleAccumulator acc;
- final Phaser phaser;
- final int incs;
- volatile double result;
- AccTask(DoubleAccumulator acc, Phaser phaser, int incs) {
- this.acc = acc;
- this.phaser = phaser;
- this.incs = incs;
- }
-
- public void run() {
+ final DoubleAccumulator acc
+ = new DoubleAccumulator((x, y) -> x + y, 0.0);
+ final int nThreads = ThreadLocalRandom.current().nextInt(1, 5);
+ final Phaser phaser = new Phaser(nThreads + 1);
+ final int incs = 1_000_000;
+ final double total = nThreads * incs/2.0 * (incs - 1); // Gauss
+ final Runnable task = () -> {
phaser.arriveAndAwaitAdvance();
- DoubleAccumulator a = acc;
- for (int i = 0; i < incs; ++i)
- a.accumulate(i);
- result = a.get();
+ for (int i = 0; i < incs; i++) {
+ acc.accumulate((double) i);
+ assertTrue(acc.get() <= total);
+ }
phaser.arrive();
+ };
+ final ExecutorService p = Executors.newCachedThreadPool();
+ try (PoolCleaner cleaner = cleaner(p)) {
+ for (int i = nThreads; i-->0; )
+ p.execute(task);
+ phaser.arriveAndAwaitAdvance();
+ phaser.arriveAndAwaitAdvance();
+ assertEquals(total, acc.get());
}
}
--- a/jdk/test/java/util/concurrent/tck/ExchangerTest.java Mon Jul 24 11:54:57 2017 +0530
+++ b/jdk/test/java/util/concurrent/tck/ExchangerTest.java Tue Jul 25 14:07:37 2017 -0700
@@ -92,7 +92,7 @@
}
/**
- * interrupt during wait for exchange throws IE
+ * interrupt during wait for exchange throws InterruptedException
*/
public void testExchange_InterruptedException() {
final Exchanger e = new Exchanger();
@@ -109,7 +109,7 @@
}
/**
- * interrupt during wait for timed exchange throws IE
+ * interrupt during wait for timed exchange throws InterruptedException
*/
public void testTimedExchange_InterruptedException() {
final Exchanger e = new Exchanger();
--- a/jdk/test/java/util/concurrent/tck/ExecutorsTest.java Mon Jul 24 11:54:57 2017 +0530
+++ b/jdk/test/java/util/concurrent/tck/ExecutorsTest.java Tue Jul 25 14:07:37 2017 -0700
@@ -167,7 +167,8 @@
}
/**
- * A new newFixedThreadPool with null ThreadFactory throws NPE
+ * A new newFixedThreadPool with null ThreadFactory throws
+ * NullPointerException
*/
public void testNewFixedThreadPool3() {
try {
@@ -177,7 +178,7 @@
}
/**
- * A new newFixedThreadPool with 0 threads throws IAE
+ * A new newFixedThreadPool with 0 threads throws IllegalArgumentException
*/
public void testNewFixedThreadPool4() {
try {
--- a/jdk/test/java/util/concurrent/tck/ForkJoinPool8Test.java Mon Jul 24 11:54:57 2017 +0530
+++ b/jdk/test/java/util/concurrent/tck/ForkJoinPool8Test.java Tue Jul 25 14:07:37 2017 -0700
@@ -32,7 +32,6 @@
*/
import static java.util.concurrent.TimeUnit.MILLISECONDS;
-import static java.util.concurrent.TimeUnit.SECONDS;
import java.util.HashSet;
import java.util.concurrent.CancellationException;
@@ -111,14 +110,14 @@
Thread.currentThread().interrupt();
try {
- a.get(5L, SECONDS);
+ a.get(randomTimeout(), randomTimeUnit());
shouldThrow();
} catch (InterruptedException success) {
} catch (Throwable fail) { threadUnexpectedException(fail); }
}
try {
- a.get(0L, SECONDS);
+ a.get(randomExpiredTimeout(), randomTimeUnit());
shouldThrow();
} catch (TimeoutException success) {
} catch (Throwable fail) { threadUnexpectedException(fail); }
@@ -136,9 +135,7 @@
assertFalse(a.cancel(true));
try {
assertNull(a.get());
- } catch (Throwable fail) { threadUnexpectedException(fail); }
- try {
- assertNull(a.get(5L, SECONDS));
+ assertNull(a.get(randomTimeout(), randomTimeUnit()));
} catch (Throwable fail) { threadUnexpectedException(fail); }
}
@@ -163,7 +160,7 @@
} catch (Throwable fail) { threadUnexpectedException(fail); }
try {
- a.get(5L, SECONDS);
+ a.get(randomTimeout(), randomTimeUnit());
shouldThrow();
} catch (CancellationException success) {
} catch (Throwable fail) { threadUnexpectedException(fail); }
@@ -194,7 +191,7 @@
} catch (Throwable fail) { threadUnexpectedException(fail); }
try {
- a.get(5L, SECONDS);
+ a.get(randomTimeout(), randomTimeUnit());
shouldThrow();
} catch (ExecutionException success) {
assertSame(t.getClass(), success.getCause().getClass());
@@ -383,7 +380,7 @@
protected void realCompute() throws Exception {
FibAction f = new FibAction(8);
assertSame(f, f.fork());
- assertNull(f.get(5L, SECONDS));
+ assertNull(f.get(LONG_DELAY_MS, MILLISECONDS));
assertEquals(21, f.result);
checkCompletedNormally(f);
}};
@@ -399,7 +396,7 @@
FibAction f = new FibAction(8);
assertSame(f, f.fork());
try {
- f.get(5L, null);
+ f.get(randomTimeout(), null);
shouldThrow();
} catch (NullPointerException success) {}
}};
@@ -499,7 +496,7 @@
FailingFibAction f = new FailingFibAction(8);
assertSame(f, f.fork());
try {
- f.get(5L, SECONDS);
+ f.get(LONG_DELAY_MS, MILLISECONDS);
shouldThrow();
} catch (ExecutionException success) {
Throwable cause = success.getCause();
@@ -591,7 +588,7 @@
assertTrue(f.cancel(true));
assertSame(f, f.fork());
try {
- f.get(5L, SECONDS);
+ f.get(LONG_DELAY_MS, MILLISECONDS);
shouldThrow();
} catch (CancellationException success) {
checkCancelled(f);
@@ -1067,7 +1064,7 @@
CCF f = new LCCF(null, 8);
assertSame(f, f.fork());
try {
- f.get(5L, null);
+ f.get(randomTimeout(), null);
shouldThrow();
} catch (NullPointerException success) {}
}};
--- a/jdk/test/java/util/concurrent/tck/ForkJoinPoolTest.java Mon Jul 24 11:54:57 2017 +0530
+++ b/jdk/test/java/util/concurrent/tck/ForkJoinPoolTest.java Tue Jul 25 14:07:37 2017 -0700
@@ -38,6 +38,7 @@
import java.security.PrivilegedExceptionAction;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
@@ -267,8 +268,8 @@
assertFalse(p.awaitTermination(Long.MIN_VALUE, MILLISECONDS));
assertFalse(p.awaitTermination(-1L, NANOSECONDS));
assertFalse(p.awaitTermination(-1L, MILLISECONDS));
- assertFalse(p.awaitTermination(0L, NANOSECONDS));
- assertFalse(p.awaitTermination(0L, MILLISECONDS));
+ assertFalse(p.awaitTermination(randomExpiredTimeout(),
+ randomTimeUnit()));
long timeoutNanos = 999999L;
long startTime = System.nanoTime();
assertFalse(p.awaitTermination(timeoutNanos, NANOSECONDS));
@@ -449,7 +450,7 @@
done.set(true);
}});
assertNull(future.get());
- assertNull(future.get(0, MILLISECONDS));
+ assertNull(future.get(randomExpiredTimeout(), randomTimeUnit()));
assertTrue(done.get());
assertTrue(future.isDone());
assertFalse(future.isCancelled());
@@ -730,13 +731,14 @@
}
/**
- * invokeAll(empty collection) returns empty collection
+ * invokeAll(empty collection) returns empty list
*/
public void testInvokeAll2() throws InterruptedException {
ExecutorService e = new ForkJoinPool(1);
+ final Collection<Callable<String>> emptyCollection
+ = Collections.emptyList();
try (PoolCleaner cleaner = cleaner(e)) {
- List<Future<String>> r
- = e.invokeAll(new ArrayList<Callable<String>>());
+ List<Future<String>> r = e.invokeAll(emptyCollection);
assertTrue(r.isEmpty());
}
}
@@ -800,7 +802,7 @@
ExecutorService e = new ForkJoinPool(1);
try (PoolCleaner cleaner = cleaner(e)) {
try {
- e.invokeAny(null, MEDIUM_DELAY_MS, MILLISECONDS);
+ e.invokeAny(null, randomTimeout(), randomTimeUnit());
shouldThrow();
} catch (NullPointerException success) {}
}
@@ -815,7 +817,7 @@
List<Callable<String>> l = new ArrayList<>();
l.add(new StringTask());
try {
- e.invokeAny(l, MEDIUM_DELAY_MS, null);
+ e.invokeAny(l, randomTimeout(), null);
shouldThrow();
} catch (NullPointerException success) {}
}
@@ -829,7 +831,7 @@
try (PoolCleaner cleaner = cleaner(e)) {
try {
e.invokeAny(new ArrayList<Callable<String>>(),
- MEDIUM_DELAY_MS, MILLISECONDS);
+ randomTimeout(), randomTimeUnit());
shouldThrow();
} catch (IllegalArgumentException success) {}
}
@@ -846,7 +848,7 @@
l.add(latchAwaitingStringTask(latch));
l.add(null);
try {
- e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
+ e.invokeAny(l, randomTimeout(), randomTimeUnit());
shouldThrow();
} catch (NullPointerException success) {}
latch.countDown();
@@ -895,7 +897,7 @@
ExecutorService e = new ForkJoinPool(1);
try (PoolCleaner cleaner = cleaner(e)) {
try {
- e.invokeAll(null, MEDIUM_DELAY_MS, MILLISECONDS);
+ e.invokeAll(null, randomTimeout(), randomTimeUnit());
shouldThrow();
} catch (NullPointerException success) {}
}
@@ -910,21 +912,23 @@
List<Callable<String>> l = new ArrayList<>();
l.add(new StringTask());
try {
- e.invokeAll(l, MEDIUM_DELAY_MS, null);
+ e.invokeAll(l, randomTimeout(), null);
shouldThrow();
} catch (NullPointerException success) {}
}
}
/**
- * timed invokeAll(empty collection) returns empty collection
+ * timed invokeAll(empty collection) returns empty list
*/
public void testTimedInvokeAll2() throws InterruptedException {
ExecutorService e = new ForkJoinPool(1);
+ final Collection<Callable<String>> emptyCollection
+ = Collections.emptyList();
try (PoolCleaner cleaner = cleaner(e)) {
List<Future<String>> r
- = e.invokeAll(new ArrayList<Callable<String>>(),
- MEDIUM_DELAY_MS, MILLISECONDS);
+ = e.invokeAll(emptyCollection,
+ randomTimeout(), randomTimeUnit());
assertTrue(r.isEmpty());
}
}
@@ -939,7 +943,7 @@
l.add(new StringTask());
l.add(null);
try {
- e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
+ e.invokeAll(l, randomTimeout(), randomTimeUnit());
shouldThrow();
} catch (NullPointerException success) {}
}
--- a/jdk/test/java/util/concurrent/tck/ForkJoinTask8Test.java Mon Jul 24 11:54:57 2017 +0530
+++ b/jdk/test/java/util/concurrent/tck/ForkJoinTask8Test.java Tue Jul 25 14:07:37 2017 -0700
@@ -32,7 +32,6 @@
*/
import static java.util.concurrent.TimeUnit.MILLISECONDS;
-import static java.util.concurrent.TimeUnit.SECONDS;
import java.util.Arrays;
import java.util.concurrent.CountDownLatch;
@@ -131,7 +130,7 @@
((BinaryAsyncAction)a).getForkJoinTaskTag());
try {
- a.get(0L, SECONDS);
+ a.get(randomExpiredTimeout(), randomTimeUnit());
shouldThrow();
} catch (TimeoutException success) {
} catch (Throwable fail) { threadUnexpectedException(fail); }
@@ -156,7 +155,7 @@
Thread.currentThread().interrupt();
long startTime = System.nanoTime();
assertSame(expected, a.join());
- assertTrue(millisElapsedSince(startTime) < SMALL_DELAY_MS);
+ assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
Thread.interrupted();
}
@@ -164,7 +163,7 @@
Thread.currentThread().interrupt();
long startTime = System.nanoTime();
a.quietlyJoin(); // should be no-op
- assertTrue(millisElapsedSince(startTime) < SMALL_DELAY_MS);
+ assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
Thread.interrupted();
}
@@ -172,9 +171,7 @@
assertFalse(a.cancel(true));
try {
assertSame(expected, a.get());
- } catch (Throwable fail) { threadUnexpectedException(fail); }
- try {
- assertSame(expected, a.get(5L, SECONDS));
+ assertSame(expected, a.get(randomTimeout(), randomTimeUnit()));
} catch (Throwable fail) { threadUnexpectedException(fail); }
}
@@ -202,7 +199,7 @@
{
long startTime = System.nanoTime();
a.quietlyJoin(); // should be no-op
- assertTrue(millisElapsedSince(startTime) < SMALL_DELAY_MS);
+ assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
}
try {
@@ -213,7 +210,7 @@
} catch (Throwable fail) { threadUnexpectedException(fail); }
try {
- a.get(5L, SECONDS);
+ a.get(randomTimeout(), randomTimeUnit());
shouldThrow();
} catch (ExecutionException success) {
assertSame(t.getClass(), success.getCause().getClass());
@@ -515,7 +512,7 @@
AsyncFib f = new AsyncFib(8);
assertSame(f, f.fork());
try {
- f.get(5L, null);
+ f.get(randomTimeout(), null);
shouldThrow();
} catch (NullPointerException success) {}
}};
--- a/jdk/test/java/util/concurrent/tck/ForkJoinTaskTest.java Mon Jul 24 11:54:57 2017 +0530
+++ b/jdk/test/java/util/concurrent/tck/ForkJoinTaskTest.java Tue Jul 25 14:07:37 2017 -0700
@@ -32,7 +32,6 @@
*/
import static java.util.concurrent.TimeUnit.MILLISECONDS;
-import static java.util.concurrent.TimeUnit.SECONDS;
import java.util.Arrays;
import java.util.HashSet;
@@ -104,7 +103,7 @@
assertNull(a.getRawResult());
try {
- a.get(0L, SECONDS);
+ a.get(randomExpiredTimeout(), randomTimeUnit());
shouldThrow();
} catch (TimeoutException success) {
} catch (Throwable fail) { threadUnexpectedException(fail); }
@@ -126,7 +125,7 @@
Thread.currentThread().interrupt();
long startTime = System.nanoTime();
assertSame(expected, a.join());
- assertTrue(millisElapsedSince(startTime) < SMALL_DELAY_MS);
+ assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
Thread.interrupted();
}
@@ -134,7 +133,7 @@
Thread.currentThread().interrupt();
long startTime = System.nanoTime();
a.quietlyJoin(); // should be no-op
- assertTrue(millisElapsedSince(startTime) < SMALL_DELAY_MS);
+ assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
Thread.interrupted();
}
@@ -142,9 +141,7 @@
assertFalse(a.cancel(true));
try {
assertSame(expected, a.get());
- } catch (Throwable fail) { threadUnexpectedException(fail); }
- try {
- assertSame(expected, a.get(5L, SECONDS));
+ assertSame(expected, a.get(randomTimeout(), randomTimeUnit()));
} catch (Throwable fail) { threadUnexpectedException(fail); }
}
@@ -169,7 +166,7 @@
{
long startTime = System.nanoTime();
a.quietlyJoin(); // should be no-op
- assertTrue(millisElapsedSince(startTime) < SMALL_DELAY_MS);
+ assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
}
try {
@@ -179,7 +176,7 @@
} catch (Throwable fail) { threadUnexpectedException(fail); }
try {
- a.get(5L, SECONDS);
+ a.get(randomTimeout(), randomTimeUnit());
shouldThrow();
} catch (CancellationException success) {
} catch (Throwable fail) { threadUnexpectedException(fail); }
@@ -207,7 +204,7 @@
{
long startTime = System.nanoTime();
a.quietlyJoin(); // should be no-op
- assertTrue(millisElapsedSince(startTime) < SMALL_DELAY_MS);
+ assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
}
try {
@@ -218,7 +215,7 @@
} catch (Throwable fail) { threadUnexpectedException(fail); }
try {
- a.get(5L, SECONDS);
+ a.get(randomTimeout(), randomTimeUnit());
shouldThrow();
} catch (ExecutionException success) {
assertSame(t.getClass(), success.getCause().getClass());
@@ -492,7 +489,7 @@
AsyncFib f = new AsyncFib(8);
assertSame(f, f.fork());
try {
- f.get(5L, null);
+ f.get(randomTimeout(), null);
shouldThrow();
} catch (NullPointerException success) {}
}};
@@ -1239,7 +1236,7 @@
AsyncFib f = new AsyncFib(8);
assertSame(f, f.fork());
try {
- f.get(5L, null);
+ f.get(randomTimeout(), null);
shouldThrow();
} catch (NullPointerException success) {}
}};
--- a/jdk/test/java/util/concurrent/tck/FutureTaskTest.java Mon Jul 24 11:54:57 2017 +0530
+++ b/jdk/test/java/util/concurrent/tck/FutureTaskTest.java Tue Jul 25 14:07:37 2017 -0700
@@ -35,7 +35,6 @@
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.concurrent.TimeUnit.NANOSECONDS;
-import static java.util.concurrent.TimeUnit.SECONDS;
import java.util.ArrayList;
import java.util.List;
@@ -135,9 +134,7 @@
try {
assertSame(expected, f.get());
- } catch (Throwable fail) { threadUnexpectedException(fail); }
- try {
- assertSame(expected, f.get(5L, SECONDS));
+ assertSame(expected, f.get(randomTimeout(), randomTimeUnit()));
} catch (Throwable fail) { threadUnexpectedException(fail); }
}
@@ -152,7 +149,7 @@
} catch (Throwable fail) { threadUnexpectedException(fail); }
try {
- f.get(5L, SECONDS);
+ f.get(randomTimeout(), randomTimeUnit());
shouldThrow();
} catch (CancellationException success) {
} catch (Throwable fail) { threadUnexpectedException(fail); }
@@ -178,7 +175,7 @@
} catch (Throwable fail) { threadUnexpectedException(fail); }
try {
- f.get(5L, SECONDS);
+ f.get(randomTimeout(), randomTimeUnit());
shouldThrow();
} catch (ExecutionException success) {
assertSame(t, success.getCause());
@@ -444,6 +441,7 @@
delay(LONG_DELAY_MS);
shouldThrow();
} catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
}});
Thread t = newStartedThread(task);
--- a/jdk/test/java/util/concurrent/tck/JSR166TestCase.java Mon Jul 24 11:54:57 2017 +0530
+++ b/jdk/test/java/util/concurrent/tck/JSR166TestCase.java Tue Jul 25 14:07:37 2017 -0700
@@ -103,18 +103,24 @@
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.Future;
+import java.util.concurrent.FutureTask;
import java.util.concurrent.RecursiveAction;
import java.util.concurrent.RecursiveTask;
+import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.Semaphore;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
@@ -665,6 +671,33 @@
public static long MEDIUM_DELAY_MS;
public static long LONG_DELAY_MS;
+ private static final long RANDOM_TIMEOUT;
+ private static final long RANDOM_EXPIRED_TIMEOUT;
+ private static final TimeUnit RANDOM_TIMEUNIT;
+ static {
+ ThreadLocalRandom rnd = ThreadLocalRandom.current();
+ long[] timeouts = { Long.MIN_VALUE, -1, 0, 1, Long.MAX_VALUE };
+ RANDOM_TIMEOUT = timeouts[rnd.nextInt(timeouts.length)];
+ RANDOM_EXPIRED_TIMEOUT = timeouts[rnd.nextInt(3)];
+ TimeUnit[] timeUnits = TimeUnit.values();
+ RANDOM_TIMEUNIT = timeUnits[rnd.nextInt(timeUnits.length)];
+ }
+
+ /**
+ * Returns a timeout for use when any value at all will do.
+ */
+ static long randomTimeout() { return RANDOM_TIMEOUT; }
+
+ /**
+ * Returns a timeout that means "no waiting", i.e. not positive.
+ */
+ static long randomExpiredTimeout() { return RANDOM_EXPIRED_TIMEOUT; }
+
+ /**
+ * Returns a random non-null TimeUnit.
+ */
+ static TimeUnit randomTimeUnit() { return RANDOM_TIMEUNIT; }
+
/**
* Returns the shortest timed delay. This can be scaled up for
* slow machines using the jsr166.delay.factor system property,
@@ -685,12 +718,17 @@
LONG_DELAY_MS = SHORT_DELAY_MS * 200;
}
+ private static final long TIMEOUT_DELAY_MS
+ = (long) (12.0 * Math.cbrt(delayFactor));
+
/**
- * Returns a timeout in milliseconds to be used in tests that
- * verify that operations block or time out.
+ * Returns a timeout in milliseconds to be used in tests that verify
+ * that operations block or time out. We want this to be longer
+ * than the OS scheduling quantum, but not too long, so don't scale
+ * linearly with delayFactor; we use "crazy" cube root instead.
*/
- long timeoutMillis() {
- return SHORT_DELAY_MS / 4;
+ static long timeoutMillis() {
+ return TIMEOUT_DELAY_MS;
}
/**
@@ -1085,8 +1123,29 @@
}
/**
+ * Checks that thread eventually enters the expected blocked thread state.
+ */
+ void assertThreadBlocks(Thread thread, Thread.State expected) {
+ // always sleep at least 1 ms, with high probability avoiding
+ // transitory states
+ for (long retries = LONG_DELAY_MS * 3 / 4; retries-->0; ) {
+ try { delay(1); }
+ catch (InterruptedException fail) {
+ fail("Unexpected InterruptedException");
+ }
+ Thread.State s = thread.getState();
+ if (s == expected)
+ return;
+ else if (s == Thread.State.TERMINATED)
+ fail("Unexpected thread termination");
+ }
+ fail("timed out waiting for thread to enter thread state " + expected);
+ }
+
+ /**
* Checks that thread does not terminate within the default
* millisecond delay of {@code timeoutMillis()}.
+ * TODO: REMOVEME
*/
void assertThreadStaysAlive(Thread thread) {
assertThreadStaysAlive(thread, timeoutMillis());
@@ -1094,6 +1153,7 @@
/**
* Checks that thread does not terminate within the given millisecond delay.
+ * TODO: REMOVEME
*/
void assertThreadStaysAlive(Thread thread, long millis) {
try {
@@ -1108,6 +1168,7 @@
/**
* Checks that the threads do not terminate within the default
* millisecond delay of {@code timeoutMillis()}.
+ * TODO: REMOVEME
*/
void assertThreadsStayAlive(Thread... threads) {
assertThreadsStayAlive(timeoutMillis(), threads);
@@ -1115,6 +1176,7 @@
/**
* Checks that the threads do not terminate within the given millisecond delay.
+ * TODO: REMOVEME
*/
void assertThreadsStayAlive(long millis, Thread... threads) {
try {
@@ -1165,6 +1227,12 @@
}
/**
+ * The maximum number of consecutive spurious wakeups we should
+ * tolerate (from APIs like LockSupport.park) before failing a test.
+ */
+ static final int MAX_SPURIOUS_WAKEUPS = 10;
+
+ /**
* The number of elements to place in collections, arrays, etc.
*/
public static final int SIZE = 20;
@@ -1633,6 +1701,14 @@
}
}
+ public void await(CyclicBarrier barrier) {
+ try {
+ barrier.await(LONG_DELAY_MS, MILLISECONDS);
+ } catch (Throwable fail) {
+ threadUnexpectedException(fail);
+ }
+ }
+
// /**
// * Spin-waits up to LONG_DELAY_MS until flag becomes true.
// */
@@ -1656,28 +1732,6 @@
public String call() { throw new NullPointerException(); }
}
- public static class CallableOne implements Callable<Integer> {
- public Integer call() { return one; }
- }
-
- public class ShortRunnable extends CheckedRunnable {
- protected void realRun() throws Throwable {
- delay(SHORT_DELAY_MS);
- }
- }
-
- public class ShortInterruptedRunnable extends CheckedInterruptedRunnable {
- protected void realRun() throws InterruptedException {
- delay(SHORT_DELAY_MS);
- }
- }
-
- public class SmallRunnable extends CheckedRunnable {
- protected void realRun() throws Throwable {
- delay(SMALL_DELAY_MS);
- }
- }
-
public class SmallPossiblyInterruptedRunnable extends CheckedRunnable {
protected void realRun() {
try {
@@ -1686,25 +1740,6 @@
}
}
- public class SmallCallable extends CheckedCallable {
- protected Object realCall() throws InterruptedException {
- delay(SMALL_DELAY_MS);
- return Boolean.TRUE;
- }
- }
-
- public class MediumRunnable extends CheckedRunnable {
- protected void realRun() throws Throwable {
- delay(MEDIUM_DELAY_MS);
- }
- }
-
- public class MediumInterruptedRunnable extends CheckedInterruptedRunnable {
- protected void realRun() throws InterruptedException {
- delay(MEDIUM_DELAY_MS);
- }
- }
-
public Runnable possiblyInterruptedRunnable(final long timeoutMillis) {
return new CheckedRunnable() {
protected void realRun() {
@@ -1714,22 +1749,6 @@
}};
}
- public class MediumPossiblyInterruptedRunnable extends CheckedRunnable {
- protected void realRun() {
- try {
- delay(MEDIUM_DELAY_MS);
- } catch (InterruptedException ok) {}
- }
- }
-
- public class LongPossiblyInterruptedRunnable extends CheckedRunnable {
- protected void realRun() {
- try {
- delay(LONG_DELAY_MS);
- } catch (InterruptedException ok) {}
- }
- }
-
/**
* For use as ThreadFactory in constructors
*/
@@ -1743,59 +1762,6 @@
boolean isDone();
}
- public static TrackedRunnable trackedRunnable(final long timeoutMillis) {
- return new TrackedRunnable() {
- private volatile boolean done = false;
- public boolean isDone() { return done; }
- public void run() {
- try {
- delay(timeoutMillis);
- done = true;
- } catch (InterruptedException ok) {}
- }
- };
- }
-
- public static class TrackedShortRunnable implements Runnable {
- public volatile boolean done = false;
- public void run() {
- try {
- delay(SHORT_DELAY_MS);
- done = true;
- } catch (InterruptedException ok) {}
- }
- }
-
- public static class TrackedSmallRunnable implements Runnable {
- public volatile boolean done = false;
- public void run() {
- try {
- delay(SMALL_DELAY_MS);
- done = true;
- } catch (InterruptedException ok) {}
- }
- }
-
- public static class TrackedMediumRunnable implements Runnable {
- public volatile boolean done = false;
- public void run() {
- try {
- delay(MEDIUM_DELAY_MS);
- done = true;
- } catch (InterruptedException ok) {}
- }
- }
-
- public static class TrackedLongRunnable implements Runnable {
- public volatile boolean done = false;
- public void run() {
- try {
- delay(LONG_DELAY_MS);
- done = true;
- } catch (InterruptedException ok) {}
- }
- }
-
public static class TrackedNoOpRunnable implements Runnable {
public volatile boolean done = false;
public void run() {
@@ -1803,17 +1769,6 @@
}
}
- public static class TrackedCallable implements Callable {
- public volatile boolean done = false;
- public Object call() {
- try {
- delay(SMALL_DELAY_MS);
- done = true;
- } catch (InterruptedException ok) {}
- return Boolean.TRUE;
- }
- }
-
/**
* Analog of CheckedRunnable for RecursiveAction
*/
@@ -1880,7 +1835,7 @@
assertEquals(0, q.size());
assertNull(q.peek());
assertNull(q.poll());
- assertNull(q.poll(0, MILLISECONDS));
+ assertNull(q.poll(randomExpiredTimeout(), randomTimeUnit()));
assertEquals(q.toString(), "[]");
assertTrue(Arrays.equals(q.toArray(), new Object[0]));
assertFalse(q.iterator().hasNext());
@@ -2031,4 +1986,176 @@
static <T> void shuffle(T[] array) {
Collections.shuffle(Arrays.asList(array), ThreadLocalRandom.current());
}
+
+ // --- Shared assertions for Executor tests ---
+
+ /**
+ * Returns maximum number of tasks that can be submitted to given
+ * pool (with bounded queue) before saturation (when submission
+ * throws RejectedExecutionException).
+ */
+ static final int saturatedSize(ThreadPoolExecutor pool) {
+ BlockingQueue<Runnable> q = pool.getQueue();
+ return pool.getMaximumPoolSize() + q.size() + q.remainingCapacity();
+ }
+
+ @SuppressWarnings("FutureReturnValueIgnored")
+ void assertNullTaskSubmissionThrowsNullPointerException(Executor e) {
+ try {
+ e.execute((Runnable) null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+
+ if (! (e instanceof ExecutorService)) return;
+ ExecutorService es = (ExecutorService) e;
+ try {
+ es.submit((Runnable) null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ try {
+ es.submit((Runnable) null, Boolean.TRUE);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ try {
+ es.submit((Callable) null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+
+ if (! (e instanceof ScheduledExecutorService)) return;
+ ScheduledExecutorService ses = (ScheduledExecutorService) e;
+ try {
+ ses.schedule((Runnable) null,
+ randomTimeout(), randomTimeUnit());
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ try {
+ ses.schedule((Callable) null,
+ randomTimeout(), randomTimeUnit());
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ try {
+ ses.scheduleAtFixedRate((Runnable) null,
+ randomTimeout(), LONG_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ try {
+ ses.scheduleWithFixedDelay((Runnable) null,
+ randomTimeout(), LONG_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ void setRejectedExecutionHandler(
+ ThreadPoolExecutor p, RejectedExecutionHandler handler) {
+ p.setRejectedExecutionHandler(handler);
+ assertSame(handler, p.getRejectedExecutionHandler());
+ }
+
+ void assertTaskSubmissionsAreRejected(ThreadPoolExecutor p) {
+ final RejectedExecutionHandler savedHandler = p.getRejectedExecutionHandler();
+ final long savedTaskCount = p.getTaskCount();
+ final long savedCompletedTaskCount = p.getCompletedTaskCount();
+ final int savedQueueSize = p.getQueue().size();
+ final boolean stock = (p.getClass().getClassLoader() == null);
+
+ Runnable r = () -> {};
+ Callable<Boolean> c = () -> Boolean.TRUE;
+
+ class Recorder implements RejectedExecutionHandler {
+ public volatile Runnable r = null;
+ public volatile ThreadPoolExecutor p = null;
+ public void reset() { r = null; p = null; }
+ public void rejectedExecution(Runnable r, ThreadPoolExecutor p) {
+ assertNull(this.r);
+ assertNull(this.p);
+ this.r = r;
+ this.p = p;
+ }
+ }
+
+ // check custom handler is invoked exactly once per task
+ Recorder recorder = new Recorder();
+ setRejectedExecutionHandler(p, recorder);
+ for (int i = 2; i--> 0; ) {
+ recorder.reset();
+ p.execute(r);
+ if (stock && p.getClass() == ThreadPoolExecutor.class)
+ assertSame(r, recorder.r);
+ assertSame(p, recorder.p);
+
+ recorder.reset();
+ assertFalse(p.submit(r).isDone());
+ if (stock) assertTrue(!((FutureTask) recorder.r).isDone());
+ assertSame(p, recorder.p);
+
+ recorder.reset();
+ assertFalse(p.submit(r, Boolean.TRUE).isDone());
+ if (stock) assertTrue(!((FutureTask) recorder.r).isDone());
+ assertSame(p, recorder.p);
+
+ recorder.reset();
+ assertFalse(p.submit(c).isDone());
+ if (stock) assertTrue(!((FutureTask) recorder.r).isDone());
+ assertSame(p, recorder.p);
+
+ if (p instanceof ScheduledExecutorService) {
+ ScheduledExecutorService s = (ScheduledExecutorService) p;
+ ScheduledFuture<?> future;
+
+ recorder.reset();
+ future = s.schedule(r, randomTimeout(), randomTimeUnit());
+ assertFalse(future.isDone());
+ if (stock) assertTrue(!((FutureTask) recorder.r).isDone());
+ assertSame(p, recorder.p);
+
+ recorder.reset();
+ future = s.schedule(c, randomTimeout(), randomTimeUnit());
+ assertFalse(future.isDone());
+ if (stock) assertTrue(!((FutureTask) recorder.r).isDone());
+ assertSame(p, recorder.p);
+
+ recorder.reset();
+ future = s.scheduleAtFixedRate(r, randomTimeout(), LONG_DELAY_MS, MILLISECONDS);
+ assertFalse(future.isDone());
+ if (stock) assertTrue(!((FutureTask) recorder.r).isDone());
+ assertSame(p, recorder.p);
+
+ recorder.reset();
+ future = s.scheduleWithFixedDelay(r, randomTimeout(), LONG_DELAY_MS, MILLISECONDS);
+ assertFalse(future.isDone());
+ if (stock) assertTrue(!((FutureTask) recorder.r).isDone());
+ assertSame(p, recorder.p);
+ }
+ }
+
+ // Checking our custom handler above should be sufficient, but
+ // we add some integration tests of standard handlers.
+ final AtomicReference<Thread> thread = new AtomicReference<>();
+ final Runnable setThread = () -> thread.set(Thread.currentThread());
+
+ setRejectedExecutionHandler(p, new ThreadPoolExecutor.AbortPolicy());
+ try {
+ p.execute(setThread);
+ shouldThrow();
+ } catch (RejectedExecutionException success) {}
+ assertNull(thread.get());
+
+ setRejectedExecutionHandler(p, new ThreadPoolExecutor.DiscardPolicy());
+ p.execute(setThread);
+ assertNull(thread.get());
+
+ setRejectedExecutionHandler(p, new ThreadPoolExecutor.CallerRunsPolicy());
+ p.execute(setThread);
+ if (p.isShutdown())
+ assertNull(thread.get());
+ else
+ assertSame(Thread.currentThread(), thread.get());
+
+ setRejectedExecutionHandler(p, savedHandler);
+
+ // check that pool was not perturbed by handlers
+ assertEquals(savedTaskCount, p.getTaskCount());
+ assertEquals(savedCompletedTaskCount, p.getCompletedTaskCount());
+ assertEquals(savedQueueSize, p.getQueue().size());
+ }
}
--- a/jdk/test/java/util/concurrent/tck/LinkedBlockingDequeTest.java Mon Jul 24 11:54:57 2017 +0530
+++ b/jdk/test/java/util/concurrent/tck/LinkedBlockingDequeTest.java Tue Jul 25 14:07:37 2017 -0700
@@ -469,7 +469,7 @@
}
/**
- * push succeeds if not full; throws ISE if full
+ * push succeeds if not full; throws IllegalStateException if full
*/
public void testPush() {
LinkedBlockingDeque q = new LinkedBlockingDeque(SIZE);
@@ -519,7 +519,7 @@
}
/**
- * add succeeds if not full; throws ISE if full
+ * add succeeds if not full; throws IllegalStateException if full
*/
public void testAdd() {
LinkedBlockingDeque q = new LinkedBlockingDeque(SIZE);
@@ -533,7 +533,7 @@
}
/**
- * addAll(this) throws IAE
+ * addAll(this) throws IllegalArgumentException
*/
public void testAddAllSelf() {
LinkedBlockingDeque q = populatedDeque(SIZE);
@@ -631,7 +631,7 @@
}});
await(pleaseInterrupt);
- assertThreadStaysAlive(t);
+ assertThreadBlocks(t, Thread.State.WAITING);
t.interrupt();
awaitTermination(t);
assertEquals(SIZE, q.size());
@@ -653,6 +653,13 @@
pleaseTake.countDown();
q.put(86);
+ Thread.currentThread().interrupt();
+ try {
+ q.put(99);
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+
pleaseInterrupt.countDown();
try {
q.put(99);
@@ -666,7 +673,7 @@
assertEquals(0, q.take());
await(pleaseInterrupt);
- assertThreadStaysAlive(t);
+ assertThreadBlocks(t, Thread.State.WAITING);
t.interrupt();
awaitTermination(t);
assertEquals(0, q.remainingCapacity());
@@ -675,7 +682,7 @@
/**
* timed offer times out if full and elements not taken
*/
- public void testTimedOffer() throws InterruptedException {
+ public void testTimedOffer() {
final LinkedBlockingDeque q = new LinkedBlockingDeque(2);
final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
Thread t = newStartedThread(new CheckedRunnable() {
@@ -685,15 +692,24 @@
long startTime = System.nanoTime();
assertFalse(q.offer(new Object(), timeoutMillis(), MILLISECONDS));
assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+
+ Thread.currentThread().interrupt();
+ try {
+ q.offer(new Object(), 2 * LONG_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+
pleaseInterrupt.countDown();
try {
q.offer(new Object(), 2 * LONG_DELAY_MS, MILLISECONDS);
shouldThrow();
} catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
}});
await(pleaseInterrupt);
- assertThreadStaysAlive(t);
+ assertThreadBlocks(t, Thread.State.TIMED_WAITING);
t.interrupt();
awaitTermination(t);
}
@@ -716,9 +732,7 @@
final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
Thread t = newStartedThread(new CheckedRunnable() {
public void realRun() throws InterruptedException {
- for (int i = 0; i < SIZE; ++i) {
- assertEquals(i, q.take());
- }
+ for (int i = 0; i < SIZE; i++) assertEquals(i, q.take());
Thread.currentThread().interrupt();
try {
@@ -736,7 +750,7 @@
}});
await(pleaseInterrupt);
- assertThreadStaysAlive(t);
+ assertThreadBlocks(t, Thread.State.WAITING);
t.interrupt();
awaitTermination(t);
}
@@ -785,24 +799,32 @@
*/
public void testInterruptedTimedPoll() throws InterruptedException {
final BlockingQueue<Integer> q = populatedDeque(SIZE);
- final CountDownLatch aboutToWait = new CountDownLatch(1);
+ final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
Thread t = newStartedThread(new CheckedRunnable() {
public void realRun() throws InterruptedException {
long startTime = System.nanoTime();
- for (int i = 0; i < SIZE; ++i) {
+ for (int i = 0; i < SIZE; i++)
assertEquals(i, (int) q.poll(LONG_DELAY_MS, MILLISECONDS));
- }
- aboutToWait.countDown();
+
+ Thread.currentThread().interrupt();
try {
q.poll(LONG_DELAY_MS, MILLISECONDS);
shouldThrow();
- } catch (InterruptedException success) {
- assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
- }
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+
+ pleaseInterrupt.countDown();
+ try {
+ q.poll(LONG_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+
+ assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
}});
- await(aboutToWait);
- waitForThreadToEnterWaitState(t);
+ await(pleaseInterrupt);
+ assertThreadBlocks(t, Thread.State.TIMED_WAITING);
t.interrupt();
awaitTermination(t);
checkEmpty(q);
@@ -861,7 +883,7 @@
}});
await(pleaseInterrupt);
- assertThreadStaysAlive(t);
+ assertThreadBlocks(t, Thread.State.WAITING);
t.interrupt();
awaitTermination(t);
assertEquals(SIZE, q.size());
@@ -896,7 +918,7 @@
assertEquals(capacity - 1, q.take());
await(pleaseInterrupt);
- assertThreadStaysAlive(t);
+ assertThreadBlocks(t, Thread.State.WAITING);
t.interrupt();
awaitTermination(t);
assertEquals(0, q.remainingCapacity());
@@ -905,7 +927,7 @@
/**
* timed offerFirst times out if full and elements not taken
*/
- public void testTimedOfferFirst() throws InterruptedException {
+ public void testTimedOfferFirst() {
final LinkedBlockingDeque q = new LinkedBlockingDeque(2);
final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
Thread t = newStartedThread(new CheckedRunnable() {
@@ -915,15 +937,24 @@
long startTime = System.nanoTime();
assertFalse(q.offerFirst(new Object(), timeoutMillis(), MILLISECONDS));
assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+
+ Thread.currentThread().interrupt();
+ try {
+ q.offerFirst(new Object(), 2 * LONG_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+
pleaseInterrupt.countDown();
try {
q.offerFirst(new Object(), 2 * LONG_DELAY_MS, MILLISECONDS);
shouldThrow();
} catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
}});
await(pleaseInterrupt);
- assertThreadStaysAlive(t);
+ assertThreadBlocks(t, Thread.State.TIMED_WAITING);
t.interrupt();
awaitTermination(t);
}
@@ -955,7 +986,7 @@
}});
await(threadStarted);
- assertThreadStaysAlive(t);
+ assertThreadBlocks(t, Thread.State.WAITING);
t.interrupt();
awaitTermination(t);
}
@@ -996,7 +1027,7 @@
}});
await(threadStarted);
- assertThreadStaysAlive(t);
+ assertThreadBlocks(t, Thread.State.WAITING);
t.interrupt();
awaitTermination(t);
}
@@ -1028,9 +1059,7 @@
final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
Thread t = newStartedThread(new CheckedRunnable() {
public void realRun() throws InterruptedException {
- for (int i = 0; i < SIZE; ++i) {
- assertEquals(i, q.takeFirst());
- }
+ for (int i = 0; i < SIZE; i++) assertEquals(i, q.takeFirst());
Thread.currentThread().interrupt();
try {
@@ -1048,7 +1077,7 @@
}});
await(pleaseInterrupt);
- assertThreadStaysAlive(t);
+ assertThreadBlocks(t, Thread.State.WAITING);
t.interrupt();
awaitTermination(t);
}
@@ -1090,9 +1119,8 @@
Thread t = newStartedThread(new CheckedRunnable() {
public void realRun() throws InterruptedException {
long startTime = System.nanoTime();
- for (int i = 0; i < SIZE; ++i) {
+ for (int i = 0; i < SIZE; i++)
assertEquals(i, q.pollFirst(LONG_DELAY_MS, MILLISECONDS));
- }
Thread.currentThread().interrupt();
try {
@@ -1107,11 +1135,12 @@
shouldThrow();
} catch (InterruptedException success) {}
assertFalse(Thread.interrupted());
+
assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
}});
await(pleaseInterrupt);
- assertThreadStaysAlive(t);
+ assertThreadBlocks(t, Thread.State.TIMED_WAITING);
t.interrupt();
awaitTermination(t);
}
@@ -1144,6 +1173,7 @@
q.pollFirst(LONG_DELAY_MS, MILLISECONDS);
shouldThrow();
} catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
}});
@@ -1152,7 +1182,7 @@
assertTrue(q.offerFirst(zero, LONG_DELAY_MS, MILLISECONDS));
assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
barrier.await();
- assertThreadStaysAlive(t);
+ assertThreadBlocks(t, Thread.State.TIMED_WAITING);
t.interrupt();
awaitTermination(t);
}
@@ -1210,7 +1240,7 @@
}});
await(pleaseInterrupt);
- assertThreadStaysAlive(t);
+ assertThreadBlocks(t, Thread.State.WAITING);
t.interrupt();
awaitTermination(t);
assertEquals(SIZE, q.size());
@@ -1232,6 +1262,13 @@
pleaseTake.countDown();
q.putLast(86);
+ Thread.currentThread().interrupt();
+ try {
+ q.putLast(99);
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+
pleaseInterrupt.countDown();
try {
q.putLast(99);
@@ -1245,7 +1282,7 @@
assertEquals(0, q.take());
await(pleaseInterrupt);
- assertThreadStaysAlive(t);
+ assertThreadBlocks(t, Thread.State.WAITING);
t.interrupt();
awaitTermination(t);
assertEquals(0, q.remainingCapacity());
@@ -1254,7 +1291,7 @@
/**
* timed offerLast times out if full and elements not taken
*/
- public void testTimedOfferLast() throws InterruptedException {
+ public void testTimedOfferLast() {
final LinkedBlockingDeque q = new LinkedBlockingDeque(2);
final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
Thread t = newStartedThread(new CheckedRunnable() {
@@ -1264,6 +1301,13 @@
long startTime = System.nanoTime();
assertFalse(q.offerLast(new Object(), timeoutMillis(), MILLISECONDS));
assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+
+ Thread.currentThread().interrupt();
+ try {
+ q.offerLast(new Object(), 2 * LONG_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (InterruptedException success) {}
+
pleaseInterrupt.countDown();
try {
q.offerLast(new Object(), 2 * LONG_DELAY_MS, MILLISECONDS);
@@ -1272,7 +1316,7 @@
}});
await(pleaseInterrupt);
- assertThreadStaysAlive(t);
+ assertThreadBlocks(t, Thread.State.TIMED_WAITING);
t.interrupt();
awaitTermination(t);
}
@@ -1295,9 +1339,8 @@
final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
Thread t = newStartedThread(new CheckedRunnable() {
public void realRun() throws InterruptedException {
- for (int i = 0; i < SIZE; ++i) {
+ for (int i = 0; i < SIZE; i++)
assertEquals(SIZE - i - 1, q.takeLast());
- }
Thread.currentThread().interrupt();
try {
@@ -1315,7 +1358,7 @@
}});
await(pleaseInterrupt);
- assertThreadStaysAlive(t);
+ assertThreadBlocks(t, Thread.State.WAITING);
t.interrupt();
awaitTermination(t);
}
@@ -1357,10 +1400,9 @@
Thread t = newStartedThread(new CheckedRunnable() {
public void realRun() throws InterruptedException {
long startTime = System.nanoTime();
- for (int i = 0; i < SIZE; ++i) {
+ for (int i = 0; i < SIZE; i++)
assertEquals(SIZE - i - 1,
q.pollLast(LONG_DELAY_MS, MILLISECONDS));
- }
Thread.currentThread().interrupt();
try {
@@ -1380,7 +1422,7 @@
}});
await(pleaseInterrupt);
- assertThreadStaysAlive(t);
+ assertThreadBlocks(t, Thread.State.TIMED_WAITING);
t.interrupt();
awaitTermination(t);
checkEmpty(q);
@@ -1426,7 +1468,7 @@
assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
barrier.await();
- assertThreadStaysAlive(t);
+ assertThreadBlocks(t, Thread.State.TIMED_WAITING);
t.interrupt();
awaitTermination(t);
}
--- a/jdk/test/java/util/concurrent/tck/LinkedBlockingQueueTest.java Mon Jul 24 11:54:57 2017 +0530
+++ b/jdk/test/java/util/concurrent/tck/LinkedBlockingQueueTest.java Tue Jul 25 14:07:37 2017 -0700
@@ -319,7 +319,7 @@
}});
await(pleaseInterrupt);
- assertThreadStaysAlive(t);
+ assertThreadBlocks(t, Thread.State.WAITING);
t.interrupt();
awaitTermination(t);
assertEquals(SIZE, q.size());
@@ -341,6 +341,13 @@
pleaseTake.countDown();
q.put(86);
+ Thread.currentThread().interrupt();
+ try {
+ q.put(99);
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+
pleaseInterrupt.countDown();
try {
q.put(99);
@@ -354,7 +361,7 @@
assertEquals(0, q.take());
await(pleaseInterrupt);
- assertThreadStaysAlive(t);
+ assertThreadBlocks(t, Thread.State.WAITING);
t.interrupt();
awaitTermination(t);
assertEquals(0, q.remainingCapacity());
@@ -370,18 +377,28 @@
public void realRun() throws InterruptedException {
q.put(new Object());
q.put(new Object());
+
long startTime = System.nanoTime();
assertFalse(q.offer(new Object(), timeoutMillis(), MILLISECONDS));
assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+
+ Thread.currentThread().interrupt();
+ try {
+ q.offer(new Object(), 2 * LONG_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+
pleaseInterrupt.countDown();
try {
q.offer(new Object(), 2 * LONG_DELAY_MS, MILLISECONDS);
shouldThrow();
} catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
}});
await(pleaseInterrupt);
- assertThreadStaysAlive(t);
+ assertThreadBlocks(t, Thread.State.TIMED_WAITING);
t.interrupt();
awaitTermination(t);
}
@@ -404,9 +421,7 @@
final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
Thread t = newStartedThread(new CheckedRunnable() {
public void realRun() throws InterruptedException {
- for (int i = 0; i < SIZE; ++i) {
- assertEquals(i, q.take());
- }
+ for (int i = 0; i < SIZE; i++) assertEquals(i, q.take());
Thread.currentThread().interrupt();
try {
@@ -424,7 +439,7 @@
}});
await(pleaseInterrupt);
- assertThreadStaysAlive(t);
+ assertThreadBlocks(t, Thread.State.WAITING);
t.interrupt();
awaitTermination(t);
}
@@ -473,24 +488,32 @@
*/
public void testInterruptedTimedPoll() throws InterruptedException {
final BlockingQueue<Integer> q = populatedQueue(SIZE);
- final CountDownLatch aboutToWait = new CountDownLatch(1);
+ final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
Thread t = newStartedThread(new CheckedRunnable() {
public void realRun() throws InterruptedException {
long startTime = System.nanoTime();
- for (int i = 0; i < SIZE; ++i) {
+ for (int i = 0; i < SIZE; i++)
assertEquals(i, (int) q.poll(LONG_DELAY_MS, MILLISECONDS));
- }
- aboutToWait.countDown();
+
+ Thread.currentThread().interrupt();
try {
q.poll(LONG_DELAY_MS, MILLISECONDS);
shouldThrow();
- } catch (InterruptedException success) {
- assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
- }
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+
+ pleaseInterrupt.countDown();
+ try {
+ q.poll(LONG_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+
+ assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
}});
- await(aboutToWait);
- waitForThreadToEnterWaitState(t);
+ await(pleaseInterrupt);
+ assertThreadBlocks(t, Thread.State.TIMED_WAITING);
t.interrupt();
awaitTermination(t);
checkEmpty(q);
--- a/jdk/test/java/util/concurrent/tck/LinkedTransferQueueTest.java Mon Jul 24 11:54:57 2017 +0530
+++ b/jdk/test/java/util/concurrent/tck/LinkedTransferQueueTest.java Tue Jul 25 14:07:37 2017 -0700
@@ -236,9 +236,7 @@
final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
Thread t = newStartedThread(new CheckedRunnable() {
public void realRun() throws InterruptedException {
- for (int i = 0; i < SIZE; ++i) {
- assertEquals(i, q.take());
- }
+ for (int i = 0; i < SIZE; i++) assertEquals(i, q.take());
Thread.currentThread().interrupt();
try {
@@ -256,7 +254,7 @@
}});
await(pleaseInterrupt);
- assertThreadStaysAlive(t);
+ assertThreadBlocks(t, Thread.State.WAITING);
t.interrupt();
awaitTermination(t);
}
@@ -307,22 +305,32 @@
*/
public void testInterruptedTimedPoll() throws InterruptedException {
final BlockingQueue<Integer> q = populatedQueue(SIZE);
- final CountDownLatch aboutToWait = new CountDownLatch(1);
+ final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
Thread t = newStartedThread(new CheckedRunnable() {
public void realRun() throws InterruptedException {
long startTime = System.nanoTime();
- for (int i = 0; i < SIZE; ++i)
+ for (int i = 0; i < SIZE; i++)
assertEquals(i, (int) q.poll(LONG_DELAY_MS, MILLISECONDS));
- aboutToWait.countDown();
+
+ Thread.currentThread().interrupt();
try {
q.poll(LONG_DELAY_MS, MILLISECONDS);
shouldThrow();
} catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+
+ pleaseInterrupt.countDown();
+ try {
+ q.poll(LONG_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+
assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
}});
- await(aboutToWait);
- waitForThreadToEnterWaitState(t);
+ await(pleaseInterrupt);
+ assertThreadBlocks(t, Thread.State.TIMED_WAITING);
t.interrupt();
awaitTermination(t);
checkEmpty(q);
@@ -344,6 +352,7 @@
q.poll(LONG_DELAY_MS, MILLISECONDS);
shouldThrow();
} catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
}});
@@ -990,7 +999,7 @@
}});
await(pleaseInterrupt);
- assertThreadStaysAlive(t);
+ assertThreadBlocks(t, Thread.State.TIMED_WAITING);
t.interrupt();
awaitTermination(t);
checkEmpty(q);
--- a/jdk/test/java/util/concurrent/tck/LockSupportTest.java Mon Jul 24 11:54:57 2017 +0530
+++ b/jdk/test/java/util/concurrent/tck/LockSupportTest.java Tue Jul 25 14:07:37 2017 -0700
@@ -71,9 +71,7 @@
void park() {
LockSupport.park();
}
- void park(long millis) {
- throw new UnsupportedOperationException();
- }
+ Thread.State parkedState() { return Thread.State.WAITING; }
},
parkUntil() {
void park(long millis) {
@@ -89,9 +87,7 @@
void park() {
LockSupport.park(theBlocker());
}
- void park(long millis) {
- throw new UnsupportedOperationException();
- }
+ Thread.State parkedState() { return Thread.State.WAITING; }
},
parkUntilBlocker() {
void park(long millis) {
@@ -106,7 +102,10 @@
};
void park() { park(2 * LONG_DELAY_MS); }
- abstract void park(long millis);
+ void park(long millis) {
+ throw new UnsupportedOperationException();
+ }
+ Thread.State parkedState() { return Thread.State.TIMED_WAITING; }
/** Returns a deadline to use with parkUntil. */
long deadline(long millis) {
@@ -213,14 +212,16 @@
Thread t = newStartedThread(new CheckedRunnable() {
public void realRun() {
pleaseInterrupt.countDown();
- do {
+ for (int tries = MAX_SPURIOUS_WAKEUPS; tries-->0; ) {
parkMethod.park();
- // park may return spuriously
- } while (! Thread.currentThread().isInterrupted());
+ if (Thread.interrupted())
+ return;
+ }
+ fail("too many consecutive spurious wakeups?");
}});
await(pleaseInterrupt);
- assertThreadStaysAlive(t);
+ assertThreadBlocks(t, parkMethod.parkedState());
t.interrupt();
awaitTermination(t);
}
@@ -248,20 +249,17 @@
}
public void testParkAfterInterrupt(final ParkMethod parkMethod) {
final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
- final AtomicBoolean pleasePark = new AtomicBoolean(false);
Thread t = newStartedThread(new CheckedRunnable() {
public void realRun() throws Exception {
pleaseInterrupt.countDown();
- while (!pleasePark.get())
+ while (!Thread.currentThread().isInterrupted())
Thread.yield();
- assertTrue(Thread.currentThread().isInterrupted());
parkMethod.park();
- assertTrue(Thread.currentThread().isInterrupted());
+ assertTrue(Thread.interrupted());
}});
await(pleaseInterrupt);
t.interrupt();
- pleasePark.set(true);
awaitTermination(t);
}
@@ -283,13 +281,13 @@
public void testParkTimesOut(final ParkMethod parkMethod) {
Thread t = newStartedThread(new CheckedRunnable() {
public void realRun() {
- for (;;) {
+ for (int tries = MAX_SPURIOUS_WAKEUPS; tries-->0; ) {
long startTime = System.nanoTime();
parkMethod.park(timeoutMillis());
- // park may return spuriously
if (millisElapsedSince(startTime) >= timeoutMillis())
return;
}
+ fail("too many consecutive spurious wakeups?");
}});
awaitTermination(t);
@@ -323,12 +321,14 @@
public void realRun() {
Thread t = Thread.currentThread();
started.countDown();
- do {
+ for (int tries = MAX_SPURIOUS_WAKEUPS; tries-->0; ) {
assertNull(LockSupport.getBlocker(t));
parkMethod.park();
assertNull(LockSupport.getBlocker(t));
- // park may return spuriously
- } while (! Thread.currentThread().isInterrupted());
+ if (Thread.interrupted())
+ return;
+ }
+ fail("too many consecutive spurious wakeups?");
}});
long startTime = System.nanoTime();
@@ -344,6 +344,8 @@
assertNull(x); // ok
if (millisElapsedSince(startTime) > LONG_DELAY_MS)
fail("timed out");
+ if (t.getState() == Thread.State.TERMINATED)
+ break;
Thread.yield();
}
}
--- a/jdk/test/java/util/concurrent/tck/LongAccumulatorTest.java Mon Jul 24 11:54:57 2017 +0530
+++ b/jdk/test/java/util/concurrent/tck/LongAccumulatorTest.java Tue Jul 25 14:07:37 2017 -0700
@@ -34,6 +34,7 @@
import java.util.concurrent.Executors;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Phaser;
+import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.atomic.LongAccumulator;
import junit.framework.Test;
@@ -48,135 +49,124 @@
}
/**
- * default constructed initializes to zero
+ * new instance initialized to supplied identity
*/
public void testConstructor() {
- LongAccumulator ai = new LongAccumulator(Long::max, 0L);
- assertEquals(0, ai.get());
+ for (long identity : new long[] { Long.MIN_VALUE, 0, Long.MAX_VALUE })
+ assertEquals(identity,
+ new LongAccumulator(Long::max, identity).get());
}
/**
* accumulate accumulates given value to current, and get returns current value
*/
public void testAccumulateAndGet() {
- LongAccumulator ai = new LongAccumulator(Long::max, 0L);
- ai.accumulate(2);
- assertEquals(2, ai.get());
- ai.accumulate(-4);
- assertEquals(2, ai.get());
- ai.accumulate(4);
- assertEquals(4, ai.get());
+ LongAccumulator acc = new LongAccumulator(Long::max, 0L);
+ acc.accumulate(2);
+ assertEquals(2, acc.get());
+ acc.accumulate(-4);
+ assertEquals(2, acc.get());
+ acc.accumulate(4);
+ assertEquals(4, acc.get());
}
/**
* reset() causes subsequent get() to return zero
*/
public void testReset() {
- LongAccumulator ai = new LongAccumulator(Long::max, 0L);
- ai.accumulate(2);
- assertEquals(2, ai.get());
- ai.reset();
- assertEquals(0, ai.get());
+ LongAccumulator acc = new LongAccumulator(Long::max, 0L);
+ acc.accumulate(2);
+ assertEquals(2, acc.get());
+ acc.reset();
+ assertEquals(0, acc.get());
}
/**
* getThenReset() returns current value; subsequent get() returns zero
*/
public void testGetThenReset() {
- LongAccumulator ai = new LongAccumulator(Long::max, 0L);
- ai.accumulate(2);
- assertEquals(2, ai.get());
- assertEquals(2, ai.getThenReset());
- assertEquals(0, ai.get());
+ LongAccumulator acc = new LongAccumulator(Long::max, 0L);
+ acc.accumulate(2);
+ assertEquals(2, acc.get());
+ assertEquals(2, acc.getThenReset());
+ assertEquals(0, acc.get());
}
/**
* toString returns current value.
*/
public void testToString() {
- LongAccumulator ai = new LongAccumulator(Long::max, 0L);
- assertEquals("0", ai.toString());
- ai.accumulate(1);
- assertEquals(Long.toString(1), ai.toString());
+ LongAccumulator acc = new LongAccumulator(Long::max, 0L);
+ assertEquals("0", acc.toString());
+ acc.accumulate(1);
+ assertEquals(Long.toString(1), acc.toString());
}
/**
* intValue returns current value.
*/
public void testIntValue() {
- LongAccumulator ai = new LongAccumulator(Long::max, 0L);
- assertEquals(0, ai.intValue());
- ai.accumulate(1);
- assertEquals(1, ai.intValue());
+ LongAccumulator acc = new LongAccumulator(Long::max, 0L);
+ assertEquals(0, acc.intValue());
+ acc.accumulate(1);
+ assertEquals(1, acc.intValue());
}
/**
* longValue returns current value.
*/
public void testLongValue() {
- LongAccumulator ai = new LongAccumulator(Long::max, 0L);
- assertEquals(0, ai.longValue());
- ai.accumulate(1);
- assertEquals(1, ai.longValue());
+ LongAccumulator acc = new LongAccumulator(Long::max, 0L);
+ assertEquals(0, acc.longValue());
+ acc.accumulate(1);
+ assertEquals(1, acc.longValue());
}
/**
* floatValue returns current value.
*/
public void testFloatValue() {
- LongAccumulator ai = new LongAccumulator(Long::max, 0L);
- assertEquals(0.0f, ai.floatValue());
- ai.accumulate(1);
- assertEquals(1.0f, ai.floatValue());
+ LongAccumulator acc = new LongAccumulator(Long::max, 0L);
+ assertEquals(0.0f, acc.floatValue());
+ acc.accumulate(1);
+ assertEquals(1.0f, acc.floatValue());
}
/**
* doubleValue returns current value.
*/
public void testDoubleValue() {
- LongAccumulator ai = new LongAccumulator(Long::max, 0L);
- assertEquals(0.0, ai.doubleValue());
- ai.accumulate(1);
- assertEquals(1.0, ai.doubleValue());
+ LongAccumulator acc = new LongAccumulator(Long::max, 0L);
+ assertEquals(0.0, acc.doubleValue());
+ acc.accumulate(1);
+ assertEquals(1.0, acc.doubleValue());
}
/**
* accumulates by multiple threads produce correct result
*/
public void testAccumulateAndGetMT() {
- final int incs = 1000000;
- final int nthreads = 4;
- final ExecutorService pool = Executors.newCachedThreadPool();
- LongAccumulator a = new LongAccumulator(Long::max, 0L);
- Phaser phaser = new Phaser(nthreads + 1);
- for (int i = 0; i < nthreads; ++i)
- pool.execute(new AccTask(a, phaser, incs));
- phaser.arriveAndAwaitAdvance();
- phaser.arriveAndAwaitAdvance();
- long expected = incs - 1;
- long result = a.get();
- assertEquals(expected, result);
- pool.shutdown();
- }
-
- static final class AccTask implements Runnable {
- final LongAccumulator acc;
- final Phaser phaser;
- final int incs;
- volatile long result;
- AccTask(LongAccumulator acc, Phaser phaser, int incs) {
- this.acc = acc;
- this.phaser = phaser;
- this.incs = incs;
- }
-
- public void run() {
+ final LongAccumulator acc
+ = new LongAccumulator((x, y) -> x + y, 0L);
+ final int nThreads = ThreadLocalRandom.current().nextInt(1, 5);
+ final Phaser phaser = new Phaser(nThreads + 1);
+ final int incs = 1_000_000;
+ final long total = nThreads * incs/2L * (incs - 1); // Gauss
+ final Runnable task = () -> {
phaser.arriveAndAwaitAdvance();
- LongAccumulator a = acc;
- for (int i = 0; i < incs; ++i)
- a.accumulate(i);
- result = a.get();
+ for (int i = 0; i < incs; i++) {
+ acc.accumulate((long) i);
+ assertTrue(acc.get() <= total);
+ }
phaser.arrive();
+ };
+ final ExecutorService p = Executors.newCachedThreadPool();
+ try (PoolCleaner cleaner = cleaner(p)) {
+ for (int i = nThreads; i-->0; )
+ p.execute(task);
+ phaser.arriveAndAwaitAdvance();
+ phaser.arriveAndAwaitAdvance();
+ assertEquals(total, acc.get());
}
}
--- a/jdk/test/java/util/concurrent/tck/PhaserTest.java Mon Jul 24 11:54:57 2017 +0530
+++ b/jdk/test/java/util/concurrent/tck/PhaserTest.java Tue Jul 25 14:07:37 2017 -0700
@@ -520,7 +520,8 @@
await(pleaseInterrupt);
assertState(phaser, 0, 1, 1);
- assertThreadsStayAlive(t1, t2);
+ assertThreadBlocks(t1, Thread.State.WAITING);
+ assertThreadBlocks(t2, Thread.State.TIMED_WAITING);
t1.interrupt();
t2.interrupt();
awaitTermination(t1);
@@ -550,7 +551,7 @@
}});
await(pleaseArrive);
- waitForThreadToEnterWaitState(t);
+ assertThreadBlocks(t, Thread.State.WAITING);
assertEquals(0, phaser.arrive());
awaitTermination(t);
@@ -578,7 +579,7 @@
}});
await(pleaseArrive);
- waitForThreadToEnterWaitState(t);
+ assertThreadBlocks(t, Thread.State.WAITING);
t.interrupt();
assertEquals(0, phaser.arrive());
awaitTermination(t);
@@ -607,7 +608,7 @@
}});
await(pleaseArrive);
- waitForThreadToEnterWaitState(t);
+ assertThreadBlocks(t, Thread.State.WAITING);
Thread.currentThread().interrupt();
assertEquals(1, phaser.arriveAndAwaitAdvance());
assertTrue(Thread.interrupted());
@@ -632,7 +633,7 @@
}});
await(pleaseInterrupt);
- waitForThreadToEnterWaitState(t);
+ assertThreadBlocks(t, Thread.State.WAITING);
t.interrupt();
Thread.currentThread().interrupt();
assertEquals(1, phaser.arriveAndAwaitAdvance());
@@ -807,7 +808,7 @@
assertEquals(THREADS, phaser.getArrivedParties());
assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
for (Thread thread : threads)
- waitForThreadToEnterWaitState(thread);
+ assertThreadBlocks(thread, Thread.State.WAITING);
for (Thread thread : threads)
assertTrue(thread.isAlive());
assertState(phaser, 0, THREADS + 1, 1);
--- a/jdk/test/java/util/concurrent/tck/PriorityBlockingQueueTest.java Mon Jul 24 11:54:57 2017 +0530
+++ b/jdk/test/java/util/concurrent/tck/PriorityBlockingQueueTest.java Tue Jul 25 14:07:37 2017 -0700
@@ -117,7 +117,7 @@
}
/**
- * Constructor throws IAE if capacity argument nonpositive
+ * Constructor throws IllegalArgumentException if capacity argument nonpositive
*/
public void testConstructor2() {
try {
@@ -256,7 +256,7 @@
}
/**
- * addAll(this) throws IAE
+ * addAll(this) throws IllegalArgumentException
*/
public void testAddAllSelf() {
PriorityBlockingQueue q = populatedQueue(SIZE);
@@ -329,7 +329,7 @@
/**
* timed offer does not time out
*/
- public void testTimedOffer() throws InterruptedException {
+ public void testTimedOffer() {
final PriorityBlockingQueue q = new PriorityBlockingQueue(2);
Thread t = newStartedThread(new CheckedRunnable() {
public void realRun() {
@@ -360,9 +360,7 @@
final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
Thread t = newStartedThread(new CheckedRunnable() {
public void realRun() throws InterruptedException {
- for (int i = 0; i < SIZE; ++i) {
- assertEquals(i, q.take());
- }
+ for (int i = 0; i < SIZE; i++) assertEquals(i, q.take());
Thread.currentThread().interrupt();
try {
@@ -380,7 +378,7 @@
}});
await(pleaseInterrupt);
- assertThreadStaysAlive(t);
+ assertThreadBlocks(t, Thread.State.WAITING);
t.interrupt();
awaitTermination(t);
}
@@ -429,24 +427,32 @@
*/
public void testInterruptedTimedPoll() throws InterruptedException {
final BlockingQueue<Integer> q = populatedQueue(SIZE);
- final CountDownLatch aboutToWait = new CountDownLatch(1);
+ final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
Thread t = newStartedThread(new CheckedRunnable() {
public void realRun() throws InterruptedException {
long startTime = System.nanoTime();
- for (int i = 0; i < SIZE; ++i) {
+ for (int i = 0; i < SIZE; i++)
assertEquals(i, (int) q.poll(LONG_DELAY_MS, MILLISECONDS));
- }
- aboutToWait.countDown();
+
+ Thread.currentThread().interrupt();
try {
q.poll(LONG_DELAY_MS, MILLISECONDS);
shouldThrow();
- } catch (InterruptedException success) {
- assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
- }
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+
+ pleaseInterrupt.countDown();
+ try {
+ q.poll(LONG_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+
+ assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
}});
- await(aboutToWait);
- waitForThreadToEnterWaitState(t);
+ await(pleaseInterrupt);
+ assertThreadBlocks(t, Thread.State.TIMED_WAITING);
t.interrupt();
awaitTermination(t);
}
--- a/jdk/test/java/util/concurrent/tck/PriorityQueueTest.java Mon Jul 24 11:54:57 2017 +0530
+++ b/jdk/test/java/util/concurrent/tck/PriorityQueueTest.java Tue Jul 25 14:07:37 2017 -0700
@@ -90,7 +90,7 @@
}
/**
- * Constructor throws IAE if capacity argument nonpositive
+ * Constructor throws IllegalArgumentException if capacity argument nonpositive
*/
public void testConstructor2() {
try {
--- a/jdk/test/java/util/concurrent/tck/RecursiveActionTest.java Mon Jul 24 11:54:57 2017 +0530
+++ b/jdk/test/java/util/concurrent/tck/RecursiveActionTest.java Tue Jul 25 14:07:37 2017 -0700
@@ -31,7 +31,7 @@
* http://creativecommons.org/publicdomain/zero/1.0/
*/
-import static java.util.concurrent.TimeUnit.SECONDS;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
import java.util.Arrays;
import java.util.HashSet;
@@ -100,14 +100,14 @@
Thread.currentThread().interrupt();
try {
- a.get(5L, SECONDS);
+ a.get(randomTimeout(), randomTimeUnit());
shouldThrow();
} catch (InterruptedException success) {
} catch (Throwable fail) { threadUnexpectedException(fail); }
}
try {
- a.get(0L, SECONDS);
+ a.get(randomExpiredTimeout(), randomTimeUnit());
shouldThrow();
} catch (TimeoutException success) {
} catch (Throwable fail) { threadUnexpectedException(fail); }
@@ -125,9 +125,7 @@
assertFalse(a.cancel(true));
try {
assertNull(a.get());
- } catch (Throwable fail) { threadUnexpectedException(fail); }
- try {
- assertNull(a.get(5L, SECONDS));
+ assertNull(a.get(randomTimeout(), randomTimeUnit()));
} catch (Throwable fail) { threadUnexpectedException(fail); }
}
@@ -152,7 +150,7 @@
} catch (Throwable fail) { threadUnexpectedException(fail); }
try {
- a.get(5L, SECONDS);
+ a.get(randomTimeout(), randomTimeUnit());
shouldThrow();
} catch (CancellationException success) {
} catch (Throwable fail) { threadUnexpectedException(fail); }
@@ -183,7 +181,7 @@
} catch (Throwable fail) { threadUnexpectedException(fail); }
try {
- a.get(5L, SECONDS);
+ a.get(randomTimeout(), randomTimeUnit());
shouldThrow();
} catch (ExecutionException success) {
assertSame(t.getClass(), success.getCause().getClass());
@@ -469,7 +467,7 @@
protected void realCompute() throws Exception {
FibAction f = new FibAction(8);
assertSame(f, f.fork());
- assertNull(f.get(5L, SECONDS));
+ assertNull(f.get(LONG_DELAY_MS, MILLISECONDS));
assertEquals(21, f.result);
checkCompletedNormally(f);
}};
@@ -485,7 +483,7 @@
FibAction f = new FibAction(8);
assertSame(f, f.fork());
try {
- f.get(5L, null);
+ f.get(randomTimeout(), null);
shouldThrow();
} catch (NullPointerException success) {}
}};
@@ -604,7 +602,7 @@
FailingFibAction f = new FailingFibAction(8);
assertSame(f, f.fork());
try {
- f.get(5L, SECONDS);
+ f.get(LONG_DELAY_MS, MILLISECONDS);
shouldThrow();
} catch (ExecutionException success) {
Throwable cause = success.getCause();
@@ -696,7 +694,7 @@
assertTrue(f.cancel(true));
assertSame(f, f.fork());
try {
- f.get(5L, SECONDS);
+ f.get(LONG_DELAY_MS, MILLISECONDS);
shouldThrow();
} catch (CancellationException success) {
checkCancelled(f);
--- a/jdk/test/java/util/concurrent/tck/RecursiveTaskTest.java Mon Jul 24 11:54:57 2017 +0530
+++ b/jdk/test/java/util/concurrent/tck/RecursiveTaskTest.java Tue Jul 25 14:07:37 2017 -0700
@@ -31,7 +31,7 @@
* http://creativecommons.org/publicdomain/zero/1.0/
*/
-import static java.util.concurrent.TimeUnit.SECONDS;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
import java.util.HashSet;
import java.util.concurrent.CancellationException;
@@ -96,14 +96,14 @@
Thread.currentThread().interrupt();
try {
- a.get(5L, SECONDS);
+ a.get(randomTimeout(), randomTimeUnit());
shouldThrow();
} catch (InterruptedException success) {
} catch (Throwable fail) { threadUnexpectedException(fail); }
}
try {
- a.get(0L, SECONDS);
+ a.get(randomExpiredTimeout(), randomTimeUnit());
shouldThrow();
} catch (TimeoutException success) {
} catch (Throwable fail) { threadUnexpectedException(fail); }
@@ -121,9 +121,7 @@
assertFalse(a.cancel(true));
try {
assertSame(expected, a.get());
- } catch (Throwable fail) { threadUnexpectedException(fail); }
- try {
- assertSame(expected, a.get(5L, SECONDS));
+ assertSame(expected, a.get(randomTimeout(), randomTimeUnit()));
} catch (Throwable fail) { threadUnexpectedException(fail); }
}
@@ -168,7 +166,7 @@
} catch (Throwable fail) { threadUnexpectedException(fail); }
try {
- a.get(5L, SECONDS);
+ a.get(randomTimeout(), randomTimeUnit());
shouldThrow();
} catch (CancellationException success) {
} catch (Throwable fail) { threadUnexpectedException(fail); }
@@ -199,7 +197,7 @@
} catch (Throwable fail) { threadUnexpectedException(fail); }
try {
- a.get(5L, SECONDS);
+ a.get(randomTimeout(), randomTimeUnit());
shouldThrow();
} catch (ExecutionException success) {
assertSame(t.getClass(), success.getCause().getClass());
@@ -320,7 +318,7 @@
public Integer realCompute() throws Exception {
FibTask f = new FibTask(8);
assertSame(f, f.fork());
- Integer r = f.get(5L, SECONDS);
+ Integer r = f.get(LONG_DELAY_MS, MILLISECONDS);
assertEquals(21, (int) r);
checkCompletedNormally(f, r);
return r;
@@ -446,7 +444,7 @@
FailingFibTask f = new FailingFibTask(8);
assertSame(f, f.fork());
try {
- Integer r = f.get(5L, SECONDS);
+ Integer r = f.get(LONG_DELAY_MS, MILLISECONDS);
shouldThrow();
} catch (ExecutionException success) {
Throwable cause = success.getCause();
@@ -543,7 +541,7 @@
assertTrue(f.cancel(true));
assertSame(f, f.fork());
try {
- Integer r = f.get(5L, SECONDS);
+ Integer r = f.get(LONG_DELAY_MS, MILLISECONDS);
shouldThrow();
} catch (CancellationException success) {
checkCancelled(f);
--- a/jdk/test/java/util/concurrent/tck/ReentrantLockTest.java Mon Jul 24 11:54:57 2017 +0530
+++ b/jdk/test/java/util/concurrent/tck/ReentrantLockTest.java Tue Jul 25 14:07:37 2017 -0700
@@ -47,6 +47,7 @@
import junit.framework.Test;
import junit.framework.TestSuite;
+@SuppressWarnings("WaitNotInLoop") // we implement spurious-wakeup freedom
public class ReentrantLockTest extends JSR166TestCase {
public static void main(String[] args) {
main(suite(), args);
@@ -912,7 +913,7 @@
public void testAwaitUninterruptibly_fair() { testAwaitUninterruptibly(true); }
public void testAwaitUninterruptibly(boolean fair) {
final ReentrantLock lock = new ReentrantLock(fair);
- final Condition c = lock.newCondition();
+ final Condition condition = lock.newCondition();
final CountDownLatch pleaseInterrupt = new CountDownLatch(2);
Thread t1 = newStartedThread(new CheckedRunnable() {
@@ -921,7 +922,7 @@
lock.lock();
pleaseInterrupt.countDown();
Thread.currentThread().interrupt();
- c.awaitUninterruptibly();
+ condition.awaitUninterruptibly();
assertTrue(Thread.interrupted());
lock.unlock();
}});
@@ -931,21 +932,20 @@
// Interrupt during awaitUninterruptibly
lock.lock();
pleaseInterrupt.countDown();
- c.awaitUninterruptibly();
+ condition.awaitUninterruptibly();
assertTrue(Thread.interrupted());
lock.unlock();
}});
await(pleaseInterrupt);
+ t2.interrupt();
lock.lock();
lock.unlock();
- t2.interrupt();
-
- assertThreadStaysAlive(t1);
- assertTrue(t2.isAlive());
+ assertThreadBlocks(t1, Thread.State.WAITING);
+ assertThreadBlocks(t2, Thread.State.WAITING);
lock.lock();
- c.signalAll();
+ condition.signalAll();
lock.unlock();
awaitTermination(t1);
--- a/jdk/test/java/util/concurrent/tck/ReentrantReadWriteLockTest.java Mon Jul 24 11:54:57 2017 +0530
+++ b/jdk/test/java/util/concurrent/tck/ReentrantReadWriteLockTest.java Tue Jul 25 14:07:37 2017 -0700
@@ -48,6 +48,7 @@
import junit.framework.Test;
import junit.framework.TestSuite;
+@SuppressWarnings("WaitNotInLoop") // we implement spurious-wakeup freedom
public class ReentrantReadWriteLockTest extends JSR166TestCase {
public static void main(String[] args) {
main(suite(), args);
@@ -1036,42 +1037,41 @@
public void testAwaitUninterruptibly() { testAwaitUninterruptibly(false); }
public void testAwaitUninterruptibly_fair() { testAwaitUninterruptibly(true); }
public void testAwaitUninterruptibly(boolean fair) {
- final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
- final Condition c = lock.writeLock().newCondition();
+ final Lock lock = new ReentrantReadWriteLock(fair).writeLock();
+ final Condition condition = lock.newCondition();
final CountDownLatch pleaseInterrupt = new CountDownLatch(2);
Thread t1 = newStartedThread(new CheckedRunnable() {
public void realRun() {
// Interrupt before awaitUninterruptibly
- lock.writeLock().lock();
+ lock.lock();
pleaseInterrupt.countDown();
Thread.currentThread().interrupt();
- c.awaitUninterruptibly();
+ condition.awaitUninterruptibly();
assertTrue(Thread.interrupted());
- lock.writeLock().unlock();
+ lock.unlock();
}});
Thread t2 = newStartedThread(new CheckedRunnable() {
public void realRun() {
// Interrupt during awaitUninterruptibly
- lock.writeLock().lock();
+ lock.lock();
pleaseInterrupt.countDown();
- c.awaitUninterruptibly();
+ condition.awaitUninterruptibly();
assertTrue(Thread.interrupted());
- lock.writeLock().unlock();
+ lock.unlock();
}});
await(pleaseInterrupt);
- lock.writeLock().lock();
- lock.writeLock().unlock();
t2.interrupt();
+ lock.lock();
+ lock.unlock();
+ assertThreadBlocks(t1, Thread.State.WAITING);
+ assertThreadBlocks(t2, Thread.State.WAITING);
- assertThreadStaysAlive(t1);
- assertTrue(t2.isAlive());
-
- lock.writeLock().lock();
- c.signalAll();
- lock.writeLock().unlock();
+ lock.lock();
+ condition.signalAll();
+ lock.unlock();
awaitTermination(t1);
awaitTermination(t2);
--- a/jdk/test/java/util/concurrent/tck/ScheduledExecutorSubclassTest.java Mon Jul 24 11:54:57 2017 +0530
+++ b/jdk/test/java/util/concurrent/tck/ScheduledExecutorSubclassTest.java Tue Jul 25 14:07:37 2017 -0700
@@ -36,6 +36,8 @@
import static java.util.concurrent.TimeUnit.SECONDS;
import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.concurrent.BlockingQueue;
@@ -52,12 +54,14 @@
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
+import java.util.stream.Stream;
import junit.framework.Test;
import junit.framework.TestSuite;
@@ -303,110 +307,67 @@
}
/**
- * execute(null) throws NPE
+ * Submitting null tasks throws NullPointerException
*/
- public void testExecuteNull() throws InterruptedException {
- final CustomExecutor p = new CustomExecutor(1);
- try (PoolCleaner cleaner = cleaner(p)) {
- try {
- p.execute(null);
- shouldThrow();
- } catch (NullPointerException success) {}
- }
- }
-
- /**
- * schedule(null) throws NPE
- */
- public void testScheduleNull() throws InterruptedException {
+ public void testNullTaskSubmission() {
final CustomExecutor p = new CustomExecutor(1);
try (PoolCleaner cleaner = cleaner(p)) {
- try {
- TrackedCallable callable = null;
- Future f = p.schedule(callable, SHORT_DELAY_MS, MILLISECONDS);
- shouldThrow();
- } catch (NullPointerException success) {}
- }
- }
-
- /**
- * execute throws RejectedExecutionException if shutdown
- */
- public void testSchedule1_RejectedExecutionException() {
- final CustomExecutor p = new CustomExecutor(1);
- try (PoolCleaner cleaner = cleaner(p)) {
- try {
- p.shutdown();
- p.schedule(new NoOpRunnable(),
- MEDIUM_DELAY_MS, MILLISECONDS);
- shouldThrow();
- } catch (RejectedExecutionException success) {
- } catch (SecurityException ok) {}
+ assertNullTaskSubmissionThrowsNullPointerException(p);
}
}
/**
- * schedule throws RejectedExecutionException if shutdown
+ * Submitted tasks are rejected when shutdown
*/
- public void testSchedule2_RejectedExecutionException() {
- final CustomExecutor p = new CustomExecutor(1);
- try (PoolCleaner cleaner = cleaner(p)) {
- try {
- p.shutdown();
- p.schedule(new NoOpCallable(),
- MEDIUM_DELAY_MS, MILLISECONDS);
- shouldThrow();
- } catch (RejectedExecutionException success) {
- } catch (SecurityException ok) {}
- }
- }
-
- /**
- * schedule callable throws RejectedExecutionException if shutdown
- */
- public void testSchedule3_RejectedExecutionException() {
- final CustomExecutor p = new CustomExecutor(1);
- try (PoolCleaner cleaner = cleaner(p)) {
- try {
- p.shutdown();
- p.schedule(new NoOpCallable(),
- MEDIUM_DELAY_MS, MILLISECONDS);
- shouldThrow();
- } catch (RejectedExecutionException success) {
- } catch (SecurityException ok) {}
- }
- }
+ public void testSubmittedTasksRejectedWhenShutdown() throws InterruptedException {
+ final CustomExecutor p = new CustomExecutor(2);
+ final ThreadLocalRandom rnd = ThreadLocalRandom.current();
+ final CountDownLatch threadsStarted = new CountDownLatch(p.getCorePoolSize());
+ final CountDownLatch done = new CountDownLatch(1);
+ final Runnable r = () -> {
+ threadsStarted.countDown();
+ for (;;) {
+ try {
+ done.await();
+ return;
+ } catch (InterruptedException shutdownNowDeliberatelyIgnored) {}
+ }};
+ final Callable<Boolean> c = () -> {
+ threadsStarted.countDown();
+ for (;;) {
+ try {
+ done.await();
+ return Boolean.TRUE;
+ } catch (InterruptedException shutdownNowDeliberatelyIgnored) {}
+ }};
- /**
- * scheduleAtFixedRate throws RejectedExecutionException if shutdown
- */
- public void testScheduleAtFixedRate1_RejectedExecutionException() {
- final CustomExecutor p = new CustomExecutor(1);
- try (PoolCleaner cleaner = cleaner(p)) {
- try {
+ try (PoolCleaner cleaner = cleaner(p, done)) {
+ for (int i = p.getCorePoolSize(); i--> 0; ) {
+ switch (rnd.nextInt(4)) {
+ case 0: p.execute(r); break;
+ case 1: assertFalse(p.submit(r).isDone()); break;
+ case 2: assertFalse(p.submit(r, Boolean.TRUE).isDone()); break;
+ case 3: assertFalse(p.submit(c).isDone()); break;
+ }
+ }
+
+ // ScheduledThreadPoolExecutor has an unbounded queue, so never saturated.
+ await(threadsStarted);
+
+ if (rnd.nextBoolean())
+ p.shutdownNow();
+ else
p.shutdown();
- p.scheduleAtFixedRate(new NoOpRunnable(),
- MEDIUM_DELAY_MS, MEDIUM_DELAY_MS, MILLISECONDS);
- shouldThrow();
- } catch (RejectedExecutionException success) {
- } catch (SecurityException ok) {}
+ // Pool is shutdown, but not yet terminated
+ assertTaskSubmissionsAreRejected(p);
+ assertFalse(p.isTerminated());
+
+ done.countDown(); // release blocking tasks
+ assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
+
+ assertTaskSubmissionsAreRejected(p);
}
- }
-
- /**
- * scheduleWithFixedDelay throws RejectedExecutionException if shutdown
- */
- public void testScheduleWithFixedDelay1_RejectedExecutionException() {
- final CustomExecutor p = new CustomExecutor(1);
- try (PoolCleaner cleaner = cleaner(p)) {
- try {
- p.shutdown();
- p.scheduleWithFixedDelay(new NoOpRunnable(),
- MEDIUM_DELAY_MS, MEDIUM_DELAY_MS, MILLISECONDS);
- shouldThrow();
- } catch (RejectedExecutionException success) {
- } catch (SecurityException ok) {}
- }
+ assertEquals(p.getCorePoolSize(), p.getCompletedTaskCount());
}
/**
@@ -445,13 +406,13 @@
public void realRun() throws InterruptedException {
threadStarted.countDown();
assertEquals(0, p.getCompletedTaskCount());
- threadProceed.await();
+ await(threadProceed);
threadDone.countDown();
}});
await(threadStarted);
assertEquals(0, p.getCompletedTaskCount());
threadProceed.countDown();
- threadDone.await();
+ await(threadDone);
long startTime = System.nanoTime();
while (p.getCompletedTaskCount() != 1) {
if (millisElapsedSince(startTime) > LONG_DELAY_MS)
@@ -812,91 +773,187 @@
* - setExecuteExistingDelayedTasksAfterShutdownPolicy
* - setContinueExistingPeriodicTasksAfterShutdownPolicy
*/
+ @SuppressWarnings("FutureReturnValueIgnored")
public void testShutdown_cancellation() throws Exception {
- Boolean[] allBooleans = { null, Boolean.FALSE, Boolean.TRUE };
- for (Boolean policy : allBooleans)
- {
- final int poolSize = 2;
+ final int poolSize = 4;
final CustomExecutor p = new CustomExecutor(poolSize);
- final boolean effectiveDelayedPolicy = (policy != Boolean.FALSE);
- final boolean effectivePeriodicPolicy = (policy == Boolean.TRUE);
- final boolean effectiveRemovePolicy = (policy == Boolean.TRUE);
- if (policy != null) {
- p.setExecuteExistingDelayedTasksAfterShutdownPolicy(policy);
- p.setContinueExistingPeriodicTasksAfterShutdownPolicy(policy);
- p.setRemoveOnCancelPolicy(policy);
- }
+ final BlockingQueue<Runnable> q = p.getQueue();
+ final ThreadLocalRandom rnd = ThreadLocalRandom.current();
+ final long delay = rnd.nextInt(2);
+ final int rounds = rnd.nextInt(1, 3);
+ final boolean effectiveDelayedPolicy;
+ final boolean effectivePeriodicPolicy;
+ final boolean effectiveRemovePolicy;
+
+ if (rnd.nextBoolean())
+ p.setExecuteExistingDelayedTasksAfterShutdownPolicy(
+ effectiveDelayedPolicy = rnd.nextBoolean());
+ else
+ effectiveDelayedPolicy = true;
assertEquals(effectiveDelayedPolicy,
p.getExecuteExistingDelayedTasksAfterShutdownPolicy());
+
+ if (rnd.nextBoolean())
+ p.setContinueExistingPeriodicTasksAfterShutdownPolicy(
+ effectivePeriodicPolicy = rnd.nextBoolean());
+ else
+ effectivePeriodicPolicy = false;
assertEquals(effectivePeriodicPolicy,
p.getContinueExistingPeriodicTasksAfterShutdownPolicy());
+
+ if (rnd.nextBoolean())
+ p.setRemoveOnCancelPolicy(
+ effectiveRemovePolicy = rnd.nextBoolean());
+ else
+ effectiveRemovePolicy = false;
assertEquals(effectiveRemovePolicy,
p.getRemoveOnCancelPolicy());
- // Strategy: Wedge the pool with poolSize "blocker" threads
+
+ final boolean periodicTasksContinue = effectivePeriodicPolicy && rnd.nextBoolean();
+
+ // Strategy: Wedge the pool with one wave of "blocker" tasks,
+ // then add a second wave that waits in the queue until unblocked.
final AtomicInteger ran = new AtomicInteger(0);
final CountDownLatch poolBlocked = new CountDownLatch(poolSize);
final CountDownLatch unblock = new CountDownLatch(1);
- final CountDownLatch periodicLatch1 = new CountDownLatch(2);
- final CountDownLatch periodicLatch2 = new CountDownLatch(2);
- Runnable task = new CheckedRunnable() { public void realRun()
- throws InterruptedException {
- poolBlocked.countDown();
- assertTrue(unblock.await(LONG_DELAY_MS, MILLISECONDS));
- ran.getAndIncrement();
- }};
- List<Future<?>> blockers = new ArrayList<>();
- List<Future<?>> periodics = new ArrayList<>();
- List<Future<?>> delayeds = new ArrayList<>();
- for (int i = 0; i < poolSize; i++)
- blockers.add(p.submit(task));
- assertTrue(poolBlocked.await(LONG_DELAY_MS, MILLISECONDS));
+ final RuntimeException exception = new RuntimeException();
+
+ class Task implements Runnable {
+ public void run() {
+ try {
+ ran.getAndIncrement();
+ poolBlocked.countDown();
+ await(unblock);
+ } catch (Throwable fail) { threadUnexpectedException(fail); }
+ }
+ }
+
+ class PeriodicTask extends Task {
+ PeriodicTask(int rounds) { this.rounds = rounds; }
+ int rounds;
+ public void run() {
+ if (--rounds == 0) super.run();
+ // throw exception to surely terminate this periodic task,
+ // but in a separate execution and in a detectable way.
+ if (rounds == -1) throw exception;
+ }
+ }
+
+ Runnable task = new Task();
+
+ List<Future<?>> immediates = new ArrayList<>();
+ List<Future<?>> delayeds = new ArrayList<>();
+ List<Future<?>> periodics = new ArrayList<>();
- periodics.add(p.scheduleAtFixedRate(countDowner(periodicLatch1),
- 1, 1, MILLISECONDS));
- periodics.add(p.scheduleWithFixedDelay(countDowner(periodicLatch2),
- 1, 1, MILLISECONDS));
- delayeds.add(p.schedule(task, 1, MILLISECONDS));
+ immediates.add(p.submit(task));
+ delayeds.add(p.schedule(task, delay, MILLISECONDS));
+ periodics.add(p.scheduleAtFixedRate(
+ new PeriodicTask(rounds), delay, 1, MILLISECONDS));
+ periodics.add(p.scheduleWithFixedDelay(
+ new PeriodicTask(rounds), delay, 1, MILLISECONDS));
+
+ await(poolBlocked);
+
+ assertEquals(poolSize, ran.get());
+ assertEquals(poolSize, p.getActiveCount());
+ assertTrue(q.isEmpty());
- assertTrue(p.getQueue().containsAll(periodics));
- assertTrue(p.getQueue().containsAll(delayeds));
+ // Add second wave of tasks.
+ immediates.add(p.submit(task));
+ delayeds.add(p.schedule(task, effectiveDelayedPolicy ? delay : LONG_DELAY_MS, MILLISECONDS));
+ periodics.add(p.scheduleAtFixedRate(
+ new PeriodicTask(rounds), delay, 1, MILLISECONDS));
+ periodics.add(p.scheduleWithFixedDelay(
+ new PeriodicTask(rounds), delay, 1, MILLISECONDS));
+
+ assertEquals(poolSize, q.size());
+ assertEquals(poolSize, ran.get());
+
+ immediates.forEach(
+ f -> assertTrue(((ScheduledFuture)f).getDelay(NANOSECONDS) <= 0L));
+
+ Stream.of(immediates, delayeds, periodics).flatMap(c -> c.stream())
+ .forEach(f -> assertFalse(f.isDone()));
+
try { p.shutdown(); } catch (SecurityException ok) { return; }
assertTrue(p.isShutdown());
+ assertTrue(p.isTerminating());
assertFalse(p.isTerminated());
- for (Future<?> periodic : periodics) {
- assertTrue(effectivePeriodicPolicy ^ periodic.isCancelled());
- assertTrue(effectivePeriodicPolicy ^ periodic.isDone());
- }
- for (Future<?> delayed : delayeds) {
- assertTrue(effectiveDelayedPolicy ^ delayed.isCancelled());
- assertTrue(effectiveDelayedPolicy ^ delayed.isDone());
- }
- if (testImplementationDetails) {
- assertEquals(effectivePeriodicPolicy,
- p.getQueue().containsAll(periodics));
- assertEquals(effectiveDelayedPolicy,
- p.getQueue().containsAll(delayeds));
- }
- // Release all pool threads
- unblock.countDown();
+
+ if (rnd.nextBoolean())
+ assertThrows(
+ RejectedExecutionException.class,
+ () -> p.submit(task),
+ () -> p.schedule(task, 1, SECONDS),
+ () -> p.scheduleAtFixedRate(
+ new PeriodicTask(1), 1, 1, SECONDS),
+ () -> p.scheduleWithFixedDelay(
+ new PeriodicTask(2), 1, 1, SECONDS));
+
+ assertTrue(q.contains(immediates.get(1)));
+ assertTrue(!effectiveDelayedPolicy
+ ^ q.contains(delayeds.get(1)));
+ assertTrue(!effectivePeriodicPolicy
+ ^ q.containsAll(periodics.subList(2, 4)));
+
+ immediates.forEach(f -> assertFalse(f.isDone()));
+
+ assertFalse(delayeds.get(0).isDone());
+ if (effectiveDelayedPolicy)
+ assertFalse(delayeds.get(1).isDone());
+ else
+ assertTrue(delayeds.get(1).isCancelled());
- for (Future<?> delayed : delayeds) {
- if (effectiveDelayedPolicy) {
- assertNull(delayed.get());
- }
+ if (effectivePeriodicPolicy)
+ periodics.forEach(
+ f -> {
+ assertFalse(f.isDone());
+ if (!periodicTasksContinue) {
+ assertTrue(f.cancel(false));
+ assertTrue(f.isCancelled());
+ }
+ });
+ else {
+ periodics.subList(0, 2).forEach(f -> assertFalse(f.isDone()));
+ periodics.subList(2, 4).forEach(f -> assertTrue(f.isCancelled()));
}
- if (effectivePeriodicPolicy) {
- assertTrue(periodicLatch1.await(LONG_DELAY_MS, MILLISECONDS));
- assertTrue(periodicLatch2.await(LONG_DELAY_MS, MILLISECONDS));
- for (Future<?> periodic : periodics) {
- assertTrue(periodic.cancel(false));
- assertTrue(periodic.isCancelled());
- assertTrue(periodic.isDone());
- }
- }
+
+ unblock.countDown(); // Release all pool threads
+
assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
+ assertFalse(p.isTerminating());
assertTrue(p.isTerminated());
- assertEquals(2 + (effectiveDelayedPolicy ? 1 : 0), ran.get());
- }}
+
+ assertTrue(q.isEmpty());
+
+ Stream.of(immediates, delayeds, periodics).flatMap(c -> c.stream())
+ .forEach(f -> assertTrue(f.isDone()));
+
+ for (Future<?> f : immediates) assertNull(f.get());
+
+ assertNull(delayeds.get(0).get());
+ if (effectiveDelayedPolicy)
+ assertNull(delayeds.get(1).get());
+ else
+ assertTrue(delayeds.get(1).isCancelled());
+
+ if (periodicTasksContinue)
+ periodics.forEach(
+ f -> {
+ try { f.get(); }
+ catch (ExecutionException success) {
+ assertSame(exception, success.getCause());
+ }
+ catch (Throwable fail) { threadUnexpectedException(fail); }
+ });
+ else
+ periodics.forEach(f -> assertTrue(f.isCancelled()));
+
+ assertEquals(poolSize + 1
+ + (effectiveDelayedPolicy ? 1 : 0)
+ + (periodicTasksContinue ? 2 : 0),
+ ran.get());
+ }
/**
* completed submit of callable returns result
@@ -948,7 +1005,7 @@
}
/**
- * invokeAny(empty collection) throws IAE
+ * invokeAny(empty collection) throws IllegalArgumentException
*/
public void testInvokeAny2() throws Exception {
final ExecutorService e = new CustomExecutor(2);
@@ -1023,12 +1080,14 @@
}
/**
- * invokeAll(empty collection) returns empty collection
+ * invokeAll(empty collection) returns empty list
*/
public void testInvokeAll2() throws Exception {
final ExecutorService e = new CustomExecutor(2);
+ final Collection<Callable<String>> emptyCollection
+ = Collections.emptyList();
try (PoolCleaner cleaner = cleaner(e)) {
- List<Future<String>> r = e.invokeAll(new ArrayList<Callable<String>>());
+ List<Future<String>> r = e.invokeAll(emptyCollection);
assertTrue(r.isEmpty());
}
}
@@ -1091,7 +1150,7 @@
final ExecutorService e = new CustomExecutor(2);
try (PoolCleaner cleaner = cleaner(e)) {
try {
- e.invokeAny(null, MEDIUM_DELAY_MS, MILLISECONDS);
+ e.invokeAny(null, randomTimeout(), randomTimeUnit());
shouldThrow();
} catch (NullPointerException success) {}
}
@@ -1106,20 +1165,22 @@
List<Callable<String>> l = new ArrayList<>();
l.add(new StringTask());
try {
- e.invokeAny(l, MEDIUM_DELAY_MS, null);
+ e.invokeAny(l, randomTimeout(), null);
shouldThrow();
} catch (NullPointerException success) {}
}
}
/**
- * timed invokeAny(empty collection) throws IAE
+ * timed invokeAny(empty collection) throws IllegalArgumentException
*/
public void testTimedInvokeAny2() throws Exception {
final ExecutorService e = new CustomExecutor(2);
+ final Collection<Callable<String>> emptyCollection
+ = Collections.emptyList();
try (PoolCleaner cleaner = cleaner(e)) {
try {
- e.invokeAny(new ArrayList<Callable<String>>(), MEDIUM_DELAY_MS, MILLISECONDS);
+ e.invokeAny(emptyCollection, randomTimeout(), randomTimeUnit());
shouldThrow();
} catch (IllegalArgumentException success) {}
}
@@ -1136,7 +1197,7 @@
l.add(latchAwaitingStringTask(latch));
l.add(null);
try {
- e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
+ e.invokeAny(l, randomTimeout(), randomTimeUnit());
shouldThrow();
} catch (NullPointerException success) {}
latch.countDown();
@@ -1179,20 +1240,20 @@
}
/**
- * timed invokeAll(null) throws NPE
+ * timed invokeAll(null) throws NullPointerException
*/
public void testTimedInvokeAll1() throws Exception {
final ExecutorService e = new CustomExecutor(2);
try (PoolCleaner cleaner = cleaner(e)) {
try {
- e.invokeAll(null, MEDIUM_DELAY_MS, MILLISECONDS);
+ e.invokeAll(null, randomTimeout(), randomTimeUnit());
shouldThrow();
} catch (NullPointerException success) {}
}
}
/**
- * timed invokeAll(,,null) throws NPE
+ * timed invokeAll(,,null) throws NullPointerException
*/
public void testTimedInvokeAllNullTimeUnit() throws Exception {
final ExecutorService e = new CustomExecutor(2);
@@ -1200,19 +1261,22 @@
List<Callable<String>> l = new ArrayList<>();
l.add(new StringTask());
try {
- e.invokeAll(l, MEDIUM_DELAY_MS, null);
+ e.invokeAll(l, randomTimeout(), null);
shouldThrow();
} catch (NullPointerException success) {}
}
}
/**
- * timed invokeAll(empty collection) returns empty collection
+ * timed invokeAll(empty collection) returns empty list
*/
public void testTimedInvokeAll2() throws Exception {
final ExecutorService e = new CustomExecutor(2);
+ final Collection<Callable<String>> emptyCollection
+ = Collections.emptyList();
try (PoolCleaner cleaner = cleaner(e)) {
- List<Future<String>> r = e.invokeAll(new ArrayList<Callable<String>>(), MEDIUM_DELAY_MS, MILLISECONDS);
+ List<Future<String>> r =
+ e.invokeAll(emptyCollection, randomTimeout(), randomTimeUnit());
assertTrue(r.isEmpty());
}
}
@@ -1227,7 +1291,7 @@
l.add(new StringTask());
l.add(null);
try {
- e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
+ e.invokeAll(l, randomTimeout(), randomTimeUnit());
shouldThrow();
} catch (NullPointerException success) {}
}
@@ -1238,11 +1302,11 @@
*/
public void testTimedInvokeAll4() throws Exception {
final ExecutorService e = new CustomExecutor(2);
+ final Collection<Callable<String>> c = new ArrayList<>();
+ c.add(new NPETask());
try (PoolCleaner cleaner = cleaner(e)) {
- List<Callable<String>> l = new ArrayList<>();
- l.add(new NPETask());
List<Future<String>> futures =
- e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
+ e.invokeAll(c, LONG_DELAY_MS, MILLISECONDS);
assertEquals(1, futures.size());
try {
futures.get(0).get();
--- a/jdk/test/java/util/concurrent/tck/ScheduledExecutorTest.java Mon Jul 24 11:54:57 2017 +0530
+++ b/jdk/test/java/util/concurrent/tck/ScheduledExecutorTest.java Tue Jul 25 14:07:37 2017 -0700
@@ -38,6 +38,8 @@
import static java.util.concurrent.TimeUnit.SECONDS;
import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.concurrent.BlockingQueue;
@@ -51,10 +53,12 @@
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
+import java.util.stream.Stream;
import junit.framework.Test;
import junit.framework.TestSuite;
@@ -77,7 +81,7 @@
final Runnable task = new CheckedRunnable() {
public void realRun() { done.countDown(); }};
p.execute(task);
- assertTrue(done.await(LONG_DELAY_MS, MILLISECONDS));
+ await(done);
}
}
@@ -98,7 +102,7 @@
Future f = p.schedule(task, timeoutMillis(), MILLISECONDS);
assertSame(Boolean.TRUE, f.get());
assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
- assertTrue(done.await(0L, MILLISECONDS));
+ assertEquals(0L, done.getCount());
}
}
@@ -247,110 +251,67 @@
}
/**
- * execute(null) throws NPE
+ * Submitting null tasks throws NullPointerException
*/
- public void testExecuteNull() throws InterruptedException {
- final ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
- try (PoolCleaner cleaner = cleaner(p)) {
- try {
- p.execute(null);
- shouldThrow();
- } catch (NullPointerException success) {}
- }
- }
-
- /**
- * schedule(null) throws NPE
- */
- public void testScheduleNull() throws InterruptedException {
+ public void testNullTaskSubmission() {
final ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
try (PoolCleaner cleaner = cleaner(p)) {
- try {
- TrackedCallable callable = null;
- Future f = p.schedule(callable, SHORT_DELAY_MS, MILLISECONDS);
- shouldThrow();
- } catch (NullPointerException success) {}
- }
- }
-
- /**
- * execute throws RejectedExecutionException if shutdown
- */
- public void testSchedule1_RejectedExecutionException() throws InterruptedException {
- final ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
- try (PoolCleaner cleaner = cleaner(p)) {
- try {
- p.shutdown();
- p.schedule(new NoOpRunnable(),
- MEDIUM_DELAY_MS, MILLISECONDS);
- shouldThrow();
- } catch (RejectedExecutionException success) {
- } catch (SecurityException ok) {}
+ assertNullTaskSubmissionThrowsNullPointerException(p);
}
}
/**
- * schedule throws RejectedExecutionException if shutdown
+ * Submitted tasks are rejected when shutdown
*/
- public void testSchedule2_RejectedExecutionException() throws InterruptedException {
+ public void testSubmittedTasksRejectedWhenShutdown() throws InterruptedException {
final ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
- try (PoolCleaner cleaner = cleaner(p)) {
- try {
- p.shutdown();
- p.schedule(new NoOpCallable(),
- MEDIUM_DELAY_MS, MILLISECONDS);
- shouldThrow();
- } catch (RejectedExecutionException success) {
- } catch (SecurityException ok) {}
- }
- }
-
- /**
- * schedule callable throws RejectedExecutionException if shutdown
- */
- public void testSchedule3_RejectedExecutionException() throws InterruptedException {
- final ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
- try (PoolCleaner cleaner = cleaner(p)) {
- try {
- p.shutdown();
- p.schedule(new NoOpCallable(),
- MEDIUM_DELAY_MS, MILLISECONDS);
- shouldThrow();
- } catch (RejectedExecutionException success) {
- } catch (SecurityException ok) {}
- }
- }
+ final ThreadLocalRandom rnd = ThreadLocalRandom.current();
+ final CountDownLatch threadsStarted = new CountDownLatch(p.getCorePoolSize());
+ final CountDownLatch done = new CountDownLatch(1);
+ final Runnable r = () -> {
+ threadsStarted.countDown();
+ for (;;) {
+ try {
+ done.await();
+ return;
+ } catch (InterruptedException shutdownNowDeliberatelyIgnored) {}
+ }};
+ final Callable<Boolean> c = () -> {
+ threadsStarted.countDown();
+ for (;;) {
+ try {
+ done.await();
+ return Boolean.TRUE;
+ } catch (InterruptedException shutdownNowDeliberatelyIgnored) {}
+ }};
- /**
- * scheduleAtFixedRate throws RejectedExecutionException if shutdown
- */
- public void testScheduleAtFixedRate1_RejectedExecutionException() throws InterruptedException {
- final ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
- try (PoolCleaner cleaner = cleaner(p)) {
- try {
+ try (PoolCleaner cleaner = cleaner(p, done)) {
+ for (int i = p.getCorePoolSize(); i--> 0; ) {
+ switch (rnd.nextInt(4)) {
+ case 0: p.execute(r); break;
+ case 1: assertFalse(p.submit(r).isDone()); break;
+ case 2: assertFalse(p.submit(r, Boolean.TRUE).isDone()); break;
+ case 3: assertFalse(p.submit(c).isDone()); break;
+ }
+ }
+
+ // ScheduledThreadPoolExecutor has an unbounded queue, so never saturated.
+ await(threadsStarted);
+
+ if (rnd.nextBoolean())
+ p.shutdownNow();
+ else
p.shutdown();
- p.scheduleAtFixedRate(new NoOpRunnable(),
- MEDIUM_DELAY_MS, MEDIUM_DELAY_MS, MILLISECONDS);
- shouldThrow();
- } catch (RejectedExecutionException success) {
- } catch (SecurityException ok) {}
+ // Pool is shutdown, but not yet terminated
+ assertTaskSubmissionsAreRejected(p);
+ assertFalse(p.isTerminated());
+
+ done.countDown(); // release blocking tasks
+ assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
+
+ assertTaskSubmissionsAreRejected(p);
}
- }
-
- /**
- * scheduleWithFixedDelay throws RejectedExecutionException if shutdown
- */
- public void testScheduleWithFixedDelay1_RejectedExecutionException() throws InterruptedException {
- final ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
- try (PoolCleaner cleaner = cleaner(p)) {
- try {
- p.shutdown();
- p.scheduleWithFixedDelay(new NoOpRunnable(),
- MEDIUM_DELAY_MS, MEDIUM_DELAY_MS, MILLISECONDS);
- shouldThrow();
- } catch (RejectedExecutionException success) {
- } catch (SecurityException ok) {}
- }
+ assertEquals(p.getCorePoolSize(), p.getCompletedTaskCount());
}
/**
@@ -389,13 +350,13 @@
public void realRun() throws InterruptedException {
threadStarted.countDown();
assertEquals(0, p.getCompletedTaskCount());
- threadProceed.await();
+ await(threadProceed);
threadDone.countDown();
}});
await(threadStarted);
assertEquals(0, p.getCompletedTaskCount());
threadProceed.countDown();
- threadDone.await();
+ await(threadDone);
long startTime = System.nanoTime();
while (p.getCompletedTaskCount() != 1) {
if (millisElapsedSince(startTime) > LONG_DELAY_MS)
@@ -534,6 +495,17 @@
}
/**
+ * The default rejected execution handler is AbortPolicy.
+ */
+ public void testDefaultRejectedExecutionHandler() {
+ final ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
+ try (PoolCleaner cleaner = cleaner(p)) {
+ assertTrue(p.getRejectedExecutionHandler()
+ instanceof ThreadPoolExecutor.AbortPolicy);
+ }
+ }
+
+ /**
* isShutdown is false before shutdown, true after
*/
public void testIsShutdown() {
@@ -759,92 +731,188 @@
* - setExecuteExistingDelayedTasksAfterShutdownPolicy
* - setContinueExistingPeriodicTasksAfterShutdownPolicy
*/
+ @SuppressWarnings("FutureReturnValueIgnored")
public void testShutdown_cancellation() throws Exception {
- Boolean[] allBooleans = { null, Boolean.FALSE, Boolean.TRUE };
- for (Boolean policy : allBooleans)
- {
- final int poolSize = 2;
+ final int poolSize = 4;
final ScheduledThreadPoolExecutor p
= new ScheduledThreadPoolExecutor(poolSize);
- final boolean effectiveDelayedPolicy = (policy != Boolean.FALSE);
- final boolean effectivePeriodicPolicy = (policy == Boolean.TRUE);
- final boolean effectiveRemovePolicy = (policy == Boolean.TRUE);
- if (policy != null) {
- p.setExecuteExistingDelayedTasksAfterShutdownPolicy(policy);
- p.setContinueExistingPeriodicTasksAfterShutdownPolicy(policy);
- p.setRemoveOnCancelPolicy(policy);
- }
+ final BlockingQueue<Runnable> q = p.getQueue();
+ final ThreadLocalRandom rnd = ThreadLocalRandom.current();
+ final long delay = rnd.nextInt(2);
+ final int rounds = rnd.nextInt(1, 3);
+ final boolean effectiveDelayedPolicy;
+ final boolean effectivePeriodicPolicy;
+ final boolean effectiveRemovePolicy;
+
+ if (rnd.nextBoolean())
+ p.setExecuteExistingDelayedTasksAfterShutdownPolicy(
+ effectiveDelayedPolicy = rnd.nextBoolean());
+ else
+ effectiveDelayedPolicy = true;
assertEquals(effectiveDelayedPolicy,
p.getExecuteExistingDelayedTasksAfterShutdownPolicy());
+
+ if (rnd.nextBoolean())
+ p.setContinueExistingPeriodicTasksAfterShutdownPolicy(
+ effectivePeriodicPolicy = rnd.nextBoolean());
+ else
+ effectivePeriodicPolicy = false;
assertEquals(effectivePeriodicPolicy,
p.getContinueExistingPeriodicTasksAfterShutdownPolicy());
+
+ if (rnd.nextBoolean())
+ p.setRemoveOnCancelPolicy(
+ effectiveRemovePolicy = rnd.nextBoolean());
+ else
+ effectiveRemovePolicy = false;
assertEquals(effectiveRemovePolicy,
p.getRemoveOnCancelPolicy());
- // Strategy: Wedge the pool with poolSize "blocker" threads
+
+ final boolean periodicTasksContinue = effectivePeriodicPolicy && rnd.nextBoolean();
+
+ // Strategy: Wedge the pool with one wave of "blocker" tasks,
+ // then add a second wave that waits in the queue until unblocked.
final AtomicInteger ran = new AtomicInteger(0);
final CountDownLatch poolBlocked = new CountDownLatch(poolSize);
final CountDownLatch unblock = new CountDownLatch(1);
- final CountDownLatch periodicLatch1 = new CountDownLatch(2);
- final CountDownLatch periodicLatch2 = new CountDownLatch(2);
- Runnable task = new CheckedRunnable() { public void realRun()
- throws InterruptedException {
- poolBlocked.countDown();
- assertTrue(unblock.await(LONG_DELAY_MS, MILLISECONDS));
- ran.getAndIncrement();
- }};
- List<Future<?>> blockers = new ArrayList<>();
- List<Future<?>> periodics = new ArrayList<>();
- List<Future<?>> delayeds = new ArrayList<>();
- for (int i = 0; i < poolSize; i++)
- blockers.add(p.submit(task));
- assertTrue(poolBlocked.await(LONG_DELAY_MS, MILLISECONDS));
+ final RuntimeException exception = new RuntimeException();
+
+ class Task implements Runnable {
+ public void run() {
+ try {
+ ran.getAndIncrement();
+ poolBlocked.countDown();
+ await(unblock);
+ } catch (Throwable fail) { threadUnexpectedException(fail); }
+ }
+ }
+
+ class PeriodicTask extends Task {
+ PeriodicTask(int rounds) { this.rounds = rounds; }
+ int rounds;
+ public void run() {
+ if (--rounds == 0) super.run();
+ // throw exception to surely terminate this periodic task,
+ // but in a separate execution and in a detectable way.
+ if (rounds == -1) throw exception;
+ }
+ }
+
+ Runnable task = new Task();
+
+ List<Future<?>> immediates = new ArrayList<>();
+ List<Future<?>> delayeds = new ArrayList<>();
+ List<Future<?>> periodics = new ArrayList<>();
- periodics.add(p.scheduleAtFixedRate(countDowner(periodicLatch1),
- 1, 1, MILLISECONDS));
- periodics.add(p.scheduleWithFixedDelay(countDowner(periodicLatch2),
- 1, 1, MILLISECONDS));
- delayeds.add(p.schedule(task, 1, MILLISECONDS));
+ immediates.add(p.submit(task));
+ delayeds.add(p.schedule(task, delay, MILLISECONDS));
+ periodics.add(p.scheduleAtFixedRate(
+ new PeriodicTask(rounds), delay, 1, MILLISECONDS));
+ periodics.add(p.scheduleWithFixedDelay(
+ new PeriodicTask(rounds), delay, 1, MILLISECONDS));
+
+ await(poolBlocked);
+
+ assertEquals(poolSize, ran.get());
+ assertEquals(poolSize, p.getActiveCount());
+ assertTrue(q.isEmpty());
- assertTrue(p.getQueue().containsAll(periodics));
- assertTrue(p.getQueue().containsAll(delayeds));
+ // Add second wave of tasks.
+ immediates.add(p.submit(task));
+ delayeds.add(p.schedule(task, effectiveDelayedPolicy ? delay : LONG_DELAY_MS, MILLISECONDS));
+ periodics.add(p.scheduleAtFixedRate(
+ new PeriodicTask(rounds), delay, 1, MILLISECONDS));
+ periodics.add(p.scheduleWithFixedDelay(
+ new PeriodicTask(rounds), delay, 1, MILLISECONDS));
+
+ assertEquals(poolSize, q.size());
+ assertEquals(poolSize, ran.get());
+
+ immediates.forEach(
+ f -> assertTrue(((ScheduledFuture)f).getDelay(NANOSECONDS) <= 0L));
+
+ Stream.of(immediates, delayeds, periodics).flatMap(c -> c.stream())
+ .forEach(f -> assertFalse(f.isDone()));
+
try { p.shutdown(); } catch (SecurityException ok) { return; }
assertTrue(p.isShutdown());
+ assertTrue(p.isTerminating());
assertFalse(p.isTerminated());
- for (Future<?> periodic : periodics) {
- assertTrue(effectivePeriodicPolicy ^ periodic.isCancelled());
- assertTrue(effectivePeriodicPolicy ^ periodic.isDone());
- }
- for (Future<?> delayed : delayeds) {
- assertTrue(effectiveDelayedPolicy ^ delayed.isCancelled());
- assertTrue(effectiveDelayedPolicy ^ delayed.isDone());
- }
- if (testImplementationDetails) {
- assertEquals(effectivePeriodicPolicy,
- p.getQueue().containsAll(periodics));
- assertEquals(effectiveDelayedPolicy,
- p.getQueue().containsAll(delayeds));
- }
- // Release all pool threads
- unblock.countDown();
+
+ if (rnd.nextBoolean())
+ assertThrows(
+ RejectedExecutionException.class,
+ () -> p.submit(task),
+ () -> p.schedule(task, 1, SECONDS),
+ () -> p.scheduleAtFixedRate(
+ new PeriodicTask(1), 1, 1, SECONDS),
+ () -> p.scheduleWithFixedDelay(
+ new PeriodicTask(2), 1, 1, SECONDS));
+
+ assertTrue(q.contains(immediates.get(1)));
+ assertTrue(!effectiveDelayedPolicy
+ ^ q.contains(delayeds.get(1)));
+ assertTrue(!effectivePeriodicPolicy
+ ^ q.containsAll(periodics.subList(2, 4)));
+
+ immediates.forEach(f -> assertFalse(f.isDone()));
+
+ assertFalse(delayeds.get(0).isDone());
+ if (effectiveDelayedPolicy)
+ assertFalse(delayeds.get(1).isDone());
+ else
+ assertTrue(delayeds.get(1).isCancelled());
- for (Future<?> delayed : delayeds) {
- if (effectiveDelayedPolicy) {
- assertNull(delayed.get());
- }
+ if (effectivePeriodicPolicy)
+ periodics.forEach(
+ f -> {
+ assertFalse(f.isDone());
+ if (!periodicTasksContinue) {
+ assertTrue(f.cancel(false));
+ assertTrue(f.isCancelled());
+ }
+ });
+ else {
+ periodics.subList(0, 2).forEach(f -> assertFalse(f.isDone()));
+ periodics.subList(2, 4).forEach(f -> assertTrue(f.isCancelled()));
}
- if (effectivePeriodicPolicy) {
- assertTrue(periodicLatch1.await(LONG_DELAY_MS, MILLISECONDS));
- assertTrue(periodicLatch2.await(LONG_DELAY_MS, MILLISECONDS));
- for (Future<?> periodic : periodics) {
- assertTrue(periodic.cancel(false));
- assertTrue(periodic.isCancelled());
- assertTrue(periodic.isDone());
- }
- }
+
+ unblock.countDown(); // Release all pool threads
+
assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
+ assertFalse(p.isTerminating());
assertTrue(p.isTerminated());
- assertEquals(2 + (effectiveDelayedPolicy ? 1 : 0), ran.get());
- }}
+
+ assertTrue(q.isEmpty());
+
+ Stream.of(immediates, delayeds, periodics).flatMap(c -> c.stream())
+ .forEach(f -> assertTrue(f.isDone()));
+
+ for (Future<?> f : immediates) assertNull(f.get());
+
+ assertNull(delayeds.get(0).get());
+ if (effectiveDelayedPolicy)
+ assertNull(delayeds.get(1).get());
+ else
+ assertTrue(delayeds.get(1).isCancelled());
+
+ if (periodicTasksContinue)
+ periodics.forEach(
+ f -> {
+ try { f.get(); }
+ catch (ExecutionException success) {
+ assertSame(exception, success.getCause());
+ }
+ catch (Throwable fail) { threadUnexpectedException(fail); }
+ });
+ else
+ periodics.forEach(f -> assertTrue(f.isCancelled()));
+
+ assertEquals(poolSize + 1
+ + (effectiveDelayedPolicy ? 1 : 0)
+ + (periodicTasksContinue ? 2 : 0),
+ ran.get());
+ }
/**
* completed submit of callable returns result
@@ -883,7 +951,7 @@
}
/**
- * invokeAny(null) throws NPE
+ * invokeAny(null) throws NullPointerException
*/
public void testInvokeAny1() throws Exception {
final ExecutorService e = new ScheduledThreadPoolExecutor(2);
@@ -896,7 +964,7 @@
}
/**
- * invokeAny(empty collection) throws IAE
+ * invokeAny(empty collection) throws IllegalArgumentException
*/
public void testInvokeAny2() throws Exception {
final ExecutorService e = new ScheduledThreadPoolExecutor(2);
@@ -909,7 +977,7 @@
}
/**
- * invokeAny(c) throws NPE if c has null elements
+ * invokeAny(c) throws NullPointerException if c has null elements
*/
public void testInvokeAny3() throws Exception {
CountDownLatch latch = new CountDownLatch(1);
@@ -971,12 +1039,14 @@
}
/**
- * invokeAll(empty collection) returns empty collection
+ * invokeAll(empty collection) returns empty list
*/
public void testInvokeAll2() throws Exception {
final ExecutorService e = new ScheduledThreadPoolExecutor(2);
+ final Collection<Callable<String>> emptyCollection
+ = Collections.emptyList();
try (PoolCleaner cleaner = cleaner(e)) {
- List<Future<String>> r = e.invokeAll(new ArrayList<Callable<String>>());
+ List<Future<String>> r = e.invokeAll(emptyCollection);
assertTrue(r.isEmpty());
}
}
@@ -1039,14 +1109,14 @@
final ExecutorService e = new ScheduledThreadPoolExecutor(2);
try (PoolCleaner cleaner = cleaner(e)) {
try {
- e.invokeAny(null, MEDIUM_DELAY_MS, MILLISECONDS);
+ e.invokeAny(null, randomTimeout(), randomTimeUnit());
shouldThrow();
} catch (NullPointerException success) {}
}
}
/**
- * timed invokeAny(,,null) throws NPE
+ * timed invokeAny(,,null) throws NullPointerException
*/
public void testTimedInvokeAnyNullTimeUnit() throws Exception {
final ExecutorService e = new ScheduledThreadPoolExecutor(2);
@@ -1054,20 +1124,22 @@
List<Callable<String>> l = new ArrayList<>();
l.add(new StringTask());
try {
- e.invokeAny(l, MEDIUM_DELAY_MS, null);
+ e.invokeAny(l, randomTimeout(), null);
shouldThrow();
} catch (NullPointerException success) {}
}
}
/**
- * timed invokeAny(empty collection) throws IAE
+ * timed invokeAny(empty collection) throws IllegalArgumentException
*/
public void testTimedInvokeAny2() throws Exception {
final ExecutorService e = new ScheduledThreadPoolExecutor(2);
+ final Collection<Callable<String>> emptyCollection
+ = Collections.emptyList();
try (PoolCleaner cleaner = cleaner(e)) {
try {
- e.invokeAny(new ArrayList<Callable<String>>(), MEDIUM_DELAY_MS, MILLISECONDS);
+ e.invokeAny(emptyCollection, randomTimeout(), randomTimeUnit());
shouldThrow();
} catch (IllegalArgumentException success) {}
}
@@ -1084,7 +1156,7 @@
l.add(latchAwaitingStringTask(latch));
l.add(null);
try {
- e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
+ e.invokeAny(l, randomTimeout(), randomTimeUnit());
shouldThrow();
} catch (NullPointerException success) {}
latch.countDown();
@@ -1133,7 +1205,7 @@
final ExecutorService e = new ScheduledThreadPoolExecutor(2);
try (PoolCleaner cleaner = cleaner(e)) {
try {
- e.invokeAll(null, MEDIUM_DELAY_MS, MILLISECONDS);
+ e.invokeAll(null, randomTimeout(), randomTimeUnit());
shouldThrow();
} catch (NullPointerException success) {}
}
@@ -1148,20 +1220,22 @@
List<Callable<String>> l = new ArrayList<>();
l.add(new StringTask());
try {
- e.invokeAll(l, MEDIUM_DELAY_MS, null);
+ e.invokeAll(l, randomTimeout(), null);
shouldThrow();
} catch (NullPointerException success) {}
}
}
/**
- * timed invokeAll(empty collection) returns empty collection
+ * timed invokeAll(empty collection) returns empty list
*/
public void testTimedInvokeAll2() throws Exception {
final ExecutorService e = new ScheduledThreadPoolExecutor(2);
+ final Collection<Callable<String>> emptyCollection
+ = Collections.emptyList();
try (PoolCleaner cleaner = cleaner(e)) {
- List<Future<String>> r = e.invokeAll(new ArrayList<Callable<String>>(),
- MEDIUM_DELAY_MS, MILLISECONDS);
+ List<Future<String>> r =
+ e.invokeAll(emptyCollection, randomTimeout(), randomTimeUnit());
assertTrue(r.isEmpty());
}
}
@@ -1176,7 +1250,7 @@
l.add(new StringTask());
l.add(null);
try {
- e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
+ e.invokeAll(l, randomTimeout(), randomTimeUnit());
shouldThrow();
} catch (NullPointerException success) {}
}
@@ -1262,18 +1336,16 @@
* one-shot task from executing.
* https://bugs.openjdk.java.net/browse/JDK-8051859
*/
+ @SuppressWarnings("FutureReturnValueIgnored")
public void testScheduleWithFixedDelay_overflow() throws Exception {
final CountDownLatch delayedDone = new CountDownLatch(1);
final CountDownLatch immediateDone = new CountDownLatch(1);
final ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
try (PoolCleaner cleaner = cleaner(p)) {
- final Runnable immediate = new Runnable() { public void run() {
- immediateDone.countDown();
- }};
- final Runnable delayed = new Runnable() { public void run() {
+ final Runnable delayed = () -> {
delayedDone.countDown();
- p.submit(immediate);
- }};
+ p.submit(() -> immediateDone.countDown());
+ };
p.scheduleWithFixedDelay(delayed, 0L, Long.MAX_VALUE, SECONDS);
await(delayedDone);
await(immediateDone);
--- a/jdk/test/java/util/concurrent/tck/SemaphoreTest.java Mon Jul 24 11:54:57 2017 +0530
+++ b/jdk/test/java/util/concurrent/tck/SemaphoreTest.java Tue Jul 25 14:07:37 2017 -0700
@@ -38,6 +38,7 @@
import java.util.Collection;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Semaphore;
+import java.util.concurrent.ThreadLocalRandom;
import junit.framework.AssertionFailedError;
import junit.framework.Test;
@@ -154,11 +155,13 @@
void acquire(Semaphore s) throws InterruptedException {
assertTrue(s.tryAcquire(2 * LONG_DELAY_MS, MILLISECONDS));
}
+ Thread.State parkedState() { return Thread.State.TIMED_WAITING; }
},
tryAcquireTimedN {
void acquire(Semaphore s, int permits) throws InterruptedException {
assertTrue(s.tryAcquire(permits, 2 * LONG_DELAY_MS, MILLISECONDS));
}
+ Thread.State parkedState() { return Thread.State.TIMED_WAITING; }
};
// Intentionally meta-circular
@@ -172,6 +175,7 @@
for (int i = 0; i < permits; i++)
acquire(s);
}
+ Thread.State parkedState() { return Thread.State.WAITING; }
}
/**
@@ -217,11 +221,10 @@
/**
* timed tryAcquire times out
*/
- public void testTryAcquire_timeout() { testTryAcquire_timeout(false); }
- public void testTryAcquire_timeout_fair() { testTryAcquire_timeout(true); }
- public void testTryAcquire_timeout(boolean fair) {
- Semaphore s = new Semaphore(0, fair);
- long startTime = System.nanoTime();
+ public void testTryAcquire_timeout() {
+ final boolean fair = ThreadLocalRandom.current().nextBoolean();
+ final Semaphore s = new Semaphore(0, fair);
+ final long startTime = System.nanoTime();
try { assertFalse(s.tryAcquire(timeoutMillis(), MILLISECONDS)); }
catch (InterruptedException e) { threadUnexpectedException(e); }
assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
@@ -230,11 +233,10 @@
/**
* timed tryAcquire(N) times out
*/
- public void testTryAcquireN_timeout() { testTryAcquireN_timeout(false); }
- public void testTryAcquireN_timeout_fair() { testTryAcquireN_timeout(true); }
- public void testTryAcquireN_timeout(boolean fair) {
- Semaphore s = new Semaphore(2, fair);
- long startTime = System.nanoTime();
+ public void testTryAcquireN_timeout() {
+ final boolean fair = ThreadLocalRandom.current().nextBoolean();
+ final Semaphore s = new Semaphore(2, fair);
+ final long startTime = System.nanoTime();
try { assertFalse(s.tryAcquire(3, timeoutMillis(), MILLISECONDS)); }
catch (InterruptedException e) { threadUnexpectedException(e); }
assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
@@ -254,7 +256,8 @@
public void testInterruptible_tryAcquireTimedN_fair() { testInterruptible(true, AcquireMethod.tryAcquireTimedN); }
public void testInterruptible(boolean fair, final AcquireMethod acquirer) {
final PublicSemaphore s = new PublicSemaphore(0, fair);
- final Semaphore pleaseInterrupt = new Semaphore(0, fair);
+ final java.util.concurrent.CyclicBarrier pleaseInterrupt
+ = new java.util.concurrent.CyclicBarrier(2);
Thread t = newStartedThread(new CheckedRunnable() {
public void realRun() {
// Interrupt before acquire
@@ -263,12 +266,7 @@
acquirer.acquire(s);
shouldThrow();
} catch (InterruptedException success) {}
-
- // Interrupt during acquire
- try {
- acquirer.acquire(s);
- shouldThrow();
- } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
// Interrupt before acquire(N)
Thread.currentThread().interrupt();
@@ -276,21 +274,31 @@
acquirer.acquire(s, 3);
shouldThrow();
} catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
- pleaseInterrupt.release();
+ // Interrupt during acquire
+ await(pleaseInterrupt);
+ try {
+ acquirer.acquire(s);
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
// Interrupt during acquire(N)
+ await(pleaseInterrupt);
try {
acquirer.acquire(s, 3);
shouldThrow();
} catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
}});
- waitForQueuedThread(s, t);
- t.interrupt();
- await(pleaseInterrupt);
- waitForQueuedThread(s, t);
- t.interrupt();
+ for (int n = 2; n-->0; ) {
+ await(pleaseInterrupt);
+ assertThreadBlocks(t, acquirer.parkedState());
+ t.interrupt();
+ }
+
awaitTermination(t);
}
@@ -328,8 +336,8 @@
waitForQueuedThread(s, t2);
t2.interrupt();
- assertThreadStaysAlive(t1);
- assertTrue(t2.isAlive());
+ assertThreadBlocks(t1, Thread.State.WAITING);
+ assertThreadBlocks(t2, Thread.State.WAITING);
s.release(2);
@@ -627,8 +635,10 @@
Thread t2 = newStartedThread(new CheckedRunnable() {
public void realRun() throws InterruptedException {
// Will fail, even though 1 permit is available
- assertFalse(s.tryAcquire(0L, MILLISECONDS));
- assertFalse(s.tryAcquire(1, 0L, MILLISECONDS));
+ assertFalse(
+ s.tryAcquire(randomExpiredTimeout(), randomTimeUnit()));
+ assertFalse(
+ s.tryAcquire(1, randomExpiredTimeout(), randomTimeUnit()));
// untimed tryAcquire will barge and succeed
assertTrue(s.tryAcquire());
--- a/jdk/test/java/util/concurrent/tck/StampedLockTest.java Mon Jul 24 11:54:57 2017 +0530
+++ b/jdk/test/java/util/concurrent/tck/StampedLockTest.java Tue Jul 25 14:07:37 2017 -0700
@@ -34,7 +34,6 @@
import static java.util.concurrent.TimeUnit.DAYS;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
-import static java.util.concurrent.TimeUnit.SECONDS;
import java.util.ArrayList;
import java.util.List;
@@ -275,9 +274,11 @@
long s = assertNonZero(lock.writeLock());
assertTrue(lock.validate(s));
assertFalse(lock.validate(lock.tryWriteLock()));
- assertFalse(lock.validate(lock.tryWriteLock(0L, SECONDS)));
+ assertFalse(lock.validate(lock.tryWriteLock(randomExpiredTimeout(),
+ randomTimeUnit())));
assertFalse(lock.validate(lock.tryReadLock()));
- assertFalse(lock.validate(lock.tryReadLock(0L, SECONDS)));
+ assertFalse(lock.validate(lock.tryWriteLock(randomExpiredTimeout(),
+ randomTimeUnit())));
assertFalse(lock.validate(lock.tryOptimisticRead()));
lock.unlockWrite(s);
}
@@ -519,7 +520,7 @@
}});
await(aboutToLock);
- waitForThreadToEnterWaitState(t);
+ assertThreadBlocks(t, Thread.State.WAITING);
assertFalse(lock.isWriteLocked());
assertTrue(lock.isReadLocked());
lock.unlockRead(rs);
@@ -573,8 +574,8 @@
Thread t2 = newStartedThread(acquireReleaseReadLock);
await(threadsStarted);
- waitForThreadToEnterWaitState(t1);
- waitForThreadToEnterWaitState(t2);
+ assertThreadBlocks(t1, Thread.State.WAITING);
+ assertThreadBlocks(t2, Thread.State.WAITING);
assertTrue(lock.isWriteLocked());
assertFalse(lock.isReadLocked());
releaseWriteLock(lock, s);
@@ -780,7 +781,7 @@
await(locked);
assertFalse(lock.validate(p));
assertEquals(0L, lock.tryOptimisticRead());
- waitForThreadToEnterWaitState(t);
+ assertThreadBlocks(t, Thread.State.WAITING);
t.interrupt();
awaitTermination(t);
assertTrue(lock.isWriteLocked());
--- a/jdk/test/java/util/concurrent/tck/SubmissionPublisherTest.java Mon Jul 24 11:54:57 2017 +0530
+++ b/jdk/test/java/util/concurrent/tck/SubmissionPublisherTest.java Tue Jul 25 14:07:37 2017 -0700
@@ -196,7 +196,8 @@
}
/**
- * A null Executor argument to SubmissionPublisher constructor throws NPE
+ * A null Executor argument to SubmissionPublisher constructor
+ * throws NullPointerException
*/
public void testConstructor3() {
try {
@@ -207,7 +208,7 @@
/**
* A negative capacity argument to SubmissionPublisher constructor
- * throws IAE
+ * throws IllegalArgumentException
*/
public void testConstructor4() {
Executor e = Executors.newFixedThreadPool(1);
@@ -219,8 +220,9 @@
/**
* A closed publisher reports isClosed with no closedException and
- * throws ISE upon attempted submission; a subsequent close or
- * closeExceptionally has no additional effect.
+ * throws IllegalStateException upon attempted submission; a
+ * subsequent close or closeExceptionally has no additional
+ * effect.
*/
public void testClose() {
SubmissionPublisher<Integer> p = basicPublisher();
@@ -240,9 +242,9 @@
/**
* A publisher closedExceptionally reports isClosed with the
- * closedException and throws ISE upon attempted submission; a
- * subsequent close or closeExceptionally has no additional
- * effect.
+ * closedException and throws IllegalStateException upon attempted
+ * submission; a subsequent close or closeExceptionally has no
+ * additional effect.
*/
public void testCloseExceptionally() {
SubmissionPublisher<Integer> p = basicPublisher();
--- a/jdk/test/java/util/concurrent/tck/SynchronousQueueTest.java Mon Jul 24 11:54:57 2017 +0530
+++ b/jdk/test/java/util/concurrent/tck/SynchronousQueueTest.java Tue Jul 25 14:07:37 2017 -0700
@@ -45,6 +45,7 @@
import java.util.concurrent.Executors;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.SynchronousQueue;
+import java.util.concurrent.ThreadLocalRandom;
import junit.framework.Test;
@@ -123,7 +124,7 @@
}
/**
- * addAll throws ISE if no active taker
+ * addAll throws IllegalStateException if no active taker
*/
public void testAddAll_ISE() { testAddAll_ISE(false); }
public void testAddAll_ISE_fair() { testAddAll_ISE(true); }
@@ -165,7 +166,7 @@
}});
await(pleaseInterrupt);
- assertThreadStaysAlive(t);
+ assertThreadBlocks(t, Thread.State.WAITING);
t.interrupt();
awaitTermination(t);
assertEquals(0, q.remainingCapacity());
@@ -185,6 +186,13 @@
pleaseTake.countDown();
q.put(one);
+ Thread.currentThread().interrupt();
+ try {
+ q.put(99);
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+
pleaseInterrupt.countDown();
try {
q.put(99);
@@ -199,7 +207,7 @@
catch (InterruptedException e) { threadUnexpectedException(e); }
await(pleaseInterrupt);
- assertThreadStaysAlive(t);
+ assertThreadBlocks(t, Thread.State.WAITING);
t.interrupt();
awaitTermination(t);
assertEquals(0, q.remainingCapacity());
@@ -208,9 +216,8 @@
/**
* timed offer times out if elements not taken
*/
- public void testTimedOffer() { testTimedOffer(false); }
- public void testTimedOffer_fair() { testTimedOffer(true); }
- public void testTimedOffer(boolean fair) {
+ public void testTimedOffer() {
+ final boolean fair = ThreadLocalRandom.current().nextBoolean();
final SynchronousQueue q = new SynchronousQueue(fair);
final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
Thread t = newStartedThread(new CheckedRunnable() {
@@ -218,15 +225,24 @@
long startTime = System.nanoTime();
assertFalse(q.offer(new Object(), timeoutMillis(), MILLISECONDS));
assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+
+ Thread.currentThread().interrupt();
+ try {
+ q.offer(new Object(), 2 * LONG_DELAY_MS, MILLISECONDS);
+ shouldThrow();
+ } catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
+
pleaseInterrupt.countDown();
try {
q.offer(new Object(), 2 * LONG_DELAY_MS, MILLISECONDS);
shouldThrow();
} catch (InterruptedException success) {}
+ assertFalse(Thread.interrupted());
}});
await(pleaseInterrupt);
- assertThreadStaysAlive(t);
+ assertThreadBlocks(t, Thread.State.TIMED_WAITING);
t.interrupt();
awaitTermination(t);
}
@@ -255,11 +271,10 @@
/**
* timed poll with nonzero timeout times out if no active putter
*/
- public void testTimedPoll() { testTimedPoll(false); }
- public void testTimedPoll_fair() { testTimedPoll(true); }
- public void testTimedPoll(boolean fair) {
+ public void testTimedPoll() {
+ final boolean fair = ThreadLocalRandom.current().nextBoolean();
final SynchronousQueue q = new SynchronousQueue(fair);
- long startTime = System.nanoTime();
+ final long startTime = System.nanoTime();
try { assertNull(q.poll(timeoutMillis(), MILLISECONDS)); }
catch (InterruptedException e) { threadUnexpectedException(e); }
assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
@@ -269,9 +284,8 @@
* timed poll before a delayed offer times out, returning null;
* after offer succeeds; on interruption throws
*/
- public void testTimedPollWithOffer() { testTimedPollWithOffer(false); }
- public void testTimedPollWithOffer_fair() { testTimedPollWithOffer(true); }
- public void testTimedPollWithOffer(boolean fair) {
+ public void testTimedPollWithOffer() {
+ final boolean fair = ThreadLocalRandom.current().nextBoolean();
final SynchronousQueue q = new SynchronousQueue(fair);
final CountDownLatch pleaseOffer = new CountDownLatch(1);
final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
@@ -309,7 +323,7 @@
assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
await(pleaseInterrupt);
- assertThreadStaysAlive(t);
+ assertThreadBlocks(t, Thread.State.TIMED_WAITING);
t.interrupt();
awaitTermination(t);
}
@@ -465,7 +479,7 @@
}
/**
- * iterator remove throws ISE
+ * iterator remove throws IllegalStateException
*/
public void testIteratorRemove() { testIteratorRemove(false); }
public void testIteratorRemove_fair() { testIteratorRemove(true); }
--- a/jdk/test/java/util/concurrent/tck/SystemTest.java Mon Jul 24 11:54:57 2017 +0530
+++ b/jdk/test/java/util/concurrent/tck/SystemTest.java Tue Jul 25 14:07:37 2017 -0700
@@ -54,43 +54,22 @@
/**
* Nanos between readings of millis is no longer than millis (plus
- * possible rounding).
+ * possible rounding), and vice versa.
* This shows only that nano timing not (much) worse than milli.
*/
- public void testNanoTime1() throws InterruptedException {
- long m1 = System.currentTimeMillis();
+ public void testNanoTime() throws InterruptedException {
+ long m0 = System.currentTimeMillis();
+ long n0 = System.nanoTime();
Thread.sleep(1);
+ long m1 = System.currentTimeMillis();
long n1 = System.nanoTime();
- Thread.sleep(SHORT_DELAY_MS);
+ Thread.sleep(50); // avoid possibly scaled SHORT_DELAY_MS
+ long m2 = System.currentTimeMillis();
long n2 = System.nanoTime();
Thread.sleep(1);
- long m2 = System.currentTimeMillis();
- long millis = m2 - m1;
- long nanos = n2 - n1;
- assertTrue(nanos >= 0);
- long nanosAsMillis = nanos / 1000000;
- assertTrue(nanosAsMillis <= millis + MILLIS_ROUND);
+ long m3 = System.currentTimeMillis();
+ long n3 = System.nanoTime();
+ assertTrue((n2 - n1) / 1_000_000 <= m3 - m0 + MILLIS_ROUND);
+ assertTrue(m2 - m1 <= (n3 - n0) / 1_000_000 + MILLIS_ROUND);
}
-
- /**
- * Millis between readings of nanos is less than nanos, adjusting
- * for rounding.
- * This shows only that nano timing not (much) worse than milli.
- */
- public void testNanoTime2() throws InterruptedException {
- long n1 = System.nanoTime();
- Thread.sleep(1);
- long m1 = System.currentTimeMillis();
- Thread.sleep(SHORT_DELAY_MS);
- long m2 = System.currentTimeMillis();
- Thread.sleep(1);
- long n2 = System.nanoTime();
- long millis = m2 - m1;
- long nanos = n2 - n1;
-
- assertTrue(nanos >= 0);
- long nanosAsMillis = nanos / 1000000;
- assertTrue(millis <= nanosAsMillis + MILLIS_ROUND);
- }
-
}
--- a/jdk/test/java/util/concurrent/tck/ThreadPoolExecutorSubclassTest.java Mon Jul 24 11:54:57 2017 +0530
+++ b/jdk/test/java/util/concurrent/tck/ThreadPoolExecutorSubclassTest.java Tue Jul 25 14:07:37 2017 -0700
@@ -37,6 +37,8 @@
import static java.util.concurrent.TimeUnit.SECONDS;
import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
@@ -48,11 +50,11 @@
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;
import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.RunnableFuture;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.TimeUnit;
@@ -1156,88 +1158,71 @@
}
/**
- * execute throws RejectedExecutionException if saturated.
+ * Submitted tasks are rejected when saturated or shutdown
*/
- public void testSaturatedExecute() {
- final CountDownLatch done = new CountDownLatch(1);
+ public void testSubmittedTasksRejectedWhenSaturatedOrShutdown() throws InterruptedException {
final ThreadPoolExecutor p =
new CustomTPE(1, 1,
LONG_DELAY_MS, MILLISECONDS,
new ArrayBlockingQueue<Runnable>(1));
- try (PoolCleaner cleaner = cleaner(p, done)) {
- Runnable task = new CheckedRunnable() {
- public void realRun() throws InterruptedException {
- await(done);
- }};
- for (int i = 0; i < 2; ++i)
- p.execute(task);
- for (int i = 0; i < 2; ++i) {
+ final int saturatedSize = saturatedSize(p);
+ final ThreadLocalRandom rnd = ThreadLocalRandom.current();
+ final CountDownLatch threadsStarted = new CountDownLatch(p.getMaximumPoolSize());
+ final CountDownLatch done = new CountDownLatch(1);
+ final Runnable r = () -> {
+ threadsStarted.countDown();
+ for (;;) {
try {
- p.execute(task);
- shouldThrow();
- } catch (RejectedExecutionException success) {}
- assertTrue(p.getTaskCount() <= 2);
- }
- }
- }
+ done.await();
+ return;
+ } catch (InterruptedException shutdownNowDeliberatelyIgnored) {}
+ }};
+ final Callable<Boolean> c = () -> {
+ threadsStarted.countDown();
+ for (;;) {
+ try {
+ done.await();
+ return Boolean.TRUE;
+ } catch (InterruptedException shutdownNowDeliberatelyIgnored) {}
+ }};
+ final boolean shutdownNow = rnd.nextBoolean();
- /**
- * executor using CallerRunsPolicy runs task if saturated.
- */
- public void testSaturatedExecute2() {
- final CountDownLatch done = new CountDownLatch(1);
- final ThreadPoolExecutor p =
- new CustomTPE(1, 1,
- LONG_DELAY_MS, MILLISECONDS,
- new ArrayBlockingQueue<Runnable>(1),
- new CustomTPE.CallerRunsPolicy());
try (PoolCleaner cleaner = cleaner(p, done)) {
- Runnable blocker = new CheckedRunnable() {
- public void realRun() throws InterruptedException {
- await(done);
- }};
- p.execute(blocker);
- TrackedNoOpRunnable[] tasks = new TrackedNoOpRunnable[5];
- for (int i = 0; i < tasks.length; i++)
- tasks[i] = new TrackedNoOpRunnable();
- for (int i = 0; i < tasks.length; i++)
- p.execute(tasks[i]);
- for (int i = 1; i < tasks.length; i++)
- assertTrue(tasks[i].done);
- assertFalse(tasks[0].done); // waiting in queue
- }
- }
+ // saturate
+ for (int i = saturatedSize; i--> 0; ) {
+ switch (rnd.nextInt(4)) {
+ case 0: p.execute(r); break;
+ case 1: assertFalse(p.submit(r).isDone()); break;
+ case 2: assertFalse(p.submit(r, Boolean.TRUE).isDone()); break;
+ case 3: assertFalse(p.submit(c).isDone()); break;
+ }
+ }
+
+ await(threadsStarted);
+ assertTaskSubmissionsAreRejected(p);
- /**
- * executor using DiscardPolicy drops task if saturated.
- */
- public void testSaturatedExecute3() {
- final TrackedNoOpRunnable[] tasks = new TrackedNoOpRunnable[5];
- for (int i = 0; i < tasks.length; ++i)
- tasks[i] = new TrackedNoOpRunnable();
- final CountDownLatch done = new CountDownLatch(1);
- final ThreadPoolExecutor p =
- new CustomTPE(1, 1,
- LONG_DELAY_MS, MILLISECONDS,
- new ArrayBlockingQueue<Runnable>(1),
- new CustomTPE.DiscardPolicy());
- try (PoolCleaner cleaner = cleaner(p, done)) {
- p.execute(awaiter(done));
+ if (shutdownNow)
+ p.shutdownNow();
+ else
+ p.shutdown();
+ // Pool is shutdown, but not yet terminated
+ assertTaskSubmissionsAreRejected(p);
+ assertFalse(p.isTerminated());
- for (TrackedNoOpRunnable task : tasks)
- p.execute(task);
- for (int i = 1; i < tasks.length; i++)
- assertFalse(tasks[i].done);
+ done.countDown(); // release blocking tasks
+ assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
+
+ assertTaskSubmissionsAreRejected(p);
}
- for (int i = 1; i < tasks.length; i++)
- assertFalse(tasks[i].done);
- assertTrue(tasks[0].done); // was waiting in queue
+ assertEquals(saturatedSize(p)
+ - (shutdownNow ? p.getQueue().remainingCapacity() : 0),
+ p.getCompletedTaskCount());
}
/**
* executor using DiscardOldestPolicy drops oldest task if saturated.
*/
- public void testSaturatedExecute4() {
+ public void testSaturatedExecute_DiscardOldestPolicy() {
final CountDownLatch done = new CountDownLatch(1);
LatchAwaiter r1 = awaiter(done);
LatchAwaiter r2 = awaiter(done);
@@ -1246,7 +1231,7 @@
new CustomTPE(1, 1,
LONG_DELAY_MS, MILLISECONDS,
new ArrayBlockingQueue<Runnable>(1),
- new CustomTPE.DiscardOldestPolicy());
+ new ThreadPoolExecutor.DiscardOldestPolicy());
try (PoolCleaner cleaner = cleaner(p, done)) {
assertEquals(LatchAwaiter.NEW, r1.state);
assertEquals(LatchAwaiter.NEW, r2.state);
@@ -1264,57 +1249,6 @@
}
/**
- * execute throws RejectedExecutionException if shutdown
- */
- public void testRejectedExecutionExceptionOnShutdown() {
- final ThreadPoolExecutor p =
- new CustomTPE(1, 1,
- LONG_DELAY_MS, MILLISECONDS,
- new ArrayBlockingQueue<Runnable>(1));
- try { p.shutdown(); } catch (SecurityException ok) { return; }
- try (PoolCleaner cleaner = cleaner(p)) {
- try {
- p.execute(new NoOpRunnable());
- shouldThrow();
- } catch (RejectedExecutionException success) {}
- }
- }
-
- /**
- * execute using CallerRunsPolicy drops task on shutdown
- */
- public void testCallerRunsOnShutdown() {
- final ThreadPoolExecutor p =
- new CustomTPE(1, 1,
- LONG_DELAY_MS, MILLISECONDS,
- new ArrayBlockingQueue<Runnable>(1),
- new CustomTPE.CallerRunsPolicy());
- try { p.shutdown(); } catch (SecurityException ok) { return; }
- try (PoolCleaner cleaner = cleaner(p)) {
- TrackedNoOpRunnable r = new TrackedNoOpRunnable();
- p.execute(r);
- assertFalse(r.done);
- }
- }
-
- /**
- * execute using DiscardPolicy drops task on shutdown
- */
- public void testDiscardOnShutdown() {
- final ThreadPoolExecutor p =
- new CustomTPE(1, 1,
- LONG_DELAY_MS, MILLISECONDS,
- new ArrayBlockingQueue<Runnable>(1),
- new CustomTPE.DiscardPolicy());
- try { p.shutdown(); } catch (SecurityException ok) { return; }
- try (PoolCleaner cleaner = cleaner(p)) {
- TrackedNoOpRunnable r = new TrackedNoOpRunnable();
- p.execute(r);
- assertFalse(r.done);
- }
- }
-
- /**
* execute using DiscardOldestPolicy drops task on shutdown
*/
public void testDiscardOldestOnShutdown() {
@@ -1322,7 +1256,7 @@
new CustomTPE(1, 1,
LONG_DELAY_MS, MILLISECONDS,
new ArrayBlockingQueue<Runnable>(1),
- new CustomTPE.DiscardOldestPolicy());
+ new ThreadPoolExecutor.DiscardOldestPolicy());
try { p.shutdown(); } catch (SecurityException ok) { return; }
try (PoolCleaner cleaner = cleaner(p)) {
@@ -1333,18 +1267,15 @@
}
/**
- * execute(null) throws NPE
+ * Submitting null tasks throws NullPointerException
*/
- public void testExecuteNull() {
+ public void testNullTaskSubmission() {
final ThreadPoolExecutor p =
new CustomTPE(1, 2,
1L, SECONDS,
new ArrayBlockingQueue<Runnable>(10));
try (PoolCleaner cleaner = cleaner(p)) {
- try {
- p.execute(null);
- shouldThrow();
- } catch (NullPointerException success) {}
+ assertNullTaskSubmissionThrowsNullPointerException(p);
}
}
@@ -1491,7 +1422,7 @@
}
/**
- * invokeAny(null) throws NPE
+ * invokeAny(null) throws NullPointerException
*/
public void testInvokeAny1() throws Exception {
final ExecutorService e =
@@ -1507,7 +1438,7 @@
}
/**
- * invokeAny(empty collection) throws IAE
+ * invokeAny(empty collection) throws IllegalArgumentException
*/
public void testInvokeAny2() throws Exception {
final ExecutorService e =
@@ -1597,15 +1528,17 @@
}
/**
- * invokeAll(empty collection) returns empty collection
+ * invokeAll(empty collection) returns empty list
*/
public void testInvokeAll2() throws Exception {
final ExecutorService e =
new CustomTPE(2, 2,
LONG_DELAY_MS, MILLISECONDS,
new ArrayBlockingQueue<Runnable>(10));
+ final Collection<Callable<String>> emptyCollection
+ = Collections.emptyList();
try (PoolCleaner cleaner = cleaner(e)) {
- List<Future<String>> r = e.invokeAll(new ArrayList<Callable<String>>());
+ List<Future<String>> r = e.invokeAll(emptyCollection);
assertTrue(r.isEmpty());
}
}
@@ -1680,7 +1613,7 @@
new ArrayBlockingQueue<Runnable>(10));
try (PoolCleaner cleaner = cleaner(e)) {
try {
- e.invokeAny(null, MEDIUM_DELAY_MS, MILLISECONDS);
+ e.invokeAny(null, randomTimeout(), randomTimeUnit());
shouldThrow();
} catch (NullPointerException success) {}
}
@@ -1698,24 +1631,25 @@
List<Callable<String>> l = new ArrayList<>();
l.add(new StringTask());
try {
- e.invokeAny(l, MEDIUM_DELAY_MS, null);
+ e.invokeAny(l, randomTimeout(), null);
shouldThrow();
} catch (NullPointerException success) {}
}
}
/**
- * timed invokeAny(empty collection) throws IAE
+ * timed invokeAny(empty collection) throws IllegalArgumentException
*/
public void testTimedInvokeAny2() throws Exception {
final ExecutorService e =
new CustomTPE(2, 2,
LONG_DELAY_MS, MILLISECONDS,
new ArrayBlockingQueue<Runnable>(10));
+ final Collection<Callable<String>> emptyCollection
+ = Collections.emptyList();
try (PoolCleaner cleaner = cleaner(e)) {
try {
- e.invokeAny(new ArrayList<Callable<String>>(),
- MEDIUM_DELAY_MS, MILLISECONDS);
+ e.invokeAny(emptyCollection, randomTimeout(), randomTimeUnit());
shouldThrow();
} catch (IllegalArgumentException success) {}
}
@@ -1735,7 +1669,7 @@
l.add(latchAwaitingStringTask(latch));
l.add(null);
try {
- e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
+ e.invokeAny(l, randomTimeout(), MILLISECONDS);
shouldThrow();
} catch (NullPointerException success) {}
latch.countDown();
@@ -1793,7 +1727,7 @@
new ArrayBlockingQueue<Runnable>(10));
try (PoolCleaner cleaner = cleaner(e)) {
try {
- e.invokeAll(null, MEDIUM_DELAY_MS, MILLISECONDS);
+ e.invokeAll(null, randomTimeout(), randomTimeUnit());
shouldThrow();
} catch (NullPointerException success) {}
}
@@ -1811,23 +1745,25 @@
List<Callable<String>> l = new ArrayList<>();
l.add(new StringTask());
try {
- e.invokeAll(l, MEDIUM_DELAY_MS, null);
+ e.invokeAll(l, randomTimeout(), null);
shouldThrow();
} catch (NullPointerException success) {}
}
}
/**
- * timed invokeAll(empty collection) returns empty collection
+ * timed invokeAll(empty collection) returns empty list
*/
public void testTimedInvokeAll2() throws Exception {
final ExecutorService e =
new CustomTPE(2, 2,
LONG_DELAY_MS, MILLISECONDS,
new ArrayBlockingQueue<Runnable>(10));
+ final Collection<Callable<String>> emptyCollection
+ = Collections.emptyList();
try (PoolCleaner cleaner = cleaner(e)) {
- List<Future<String>> r = e.invokeAll(new ArrayList<Callable<String>>(),
- MEDIUM_DELAY_MS, MILLISECONDS);
+ List<Future<String>> r =
+ e.invokeAll(emptyCollection, randomTimeout(), randomTimeUnit());
assertTrue(r.isEmpty());
}
}
@@ -1845,7 +1781,7 @@
l.add(new StringTask());
l.add(null);
try {
- e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
+ e.invokeAll(l, randomTimeout(), randomTimeUnit());
shouldThrow();
} catch (NullPointerException success) {}
}
--- a/jdk/test/java/util/concurrent/tck/ThreadPoolExecutorTest.java Mon Jul 24 11:54:57 2017 +0530
+++ b/jdk/test/java/util/concurrent/tck/ThreadPoolExecutorTest.java Tue Jul 25 14:07:37 2017 -0700
@@ -38,6 +38,8 @@
import static java.util.concurrent.TimeUnit.SECONDS;
import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
@@ -53,8 +55,14 @@
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.ThreadPoolExecutor.AbortPolicy;
+import java.util.concurrent.ThreadPoolExecutor.CallerRunsPolicy;
+import java.util.concurrent.ThreadPoolExecutor.DiscardPolicy;
+import java.util.concurrent.ThreadPoolExecutor.DiscardOldestPolicy;
import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicReference;
import junit.framework.Test;
import junit.framework.TestSuite;
@@ -309,8 +317,7 @@
LONG_DELAY_MS, MILLISECONDS,
new ArrayBlockingQueue<Runnable>(10));
try (PoolCleaner cleaner = cleaner(p)) {
- assertTrue(p.getRejectedExecutionHandler()
- instanceof ThreadPoolExecutor.AbortPolicy);
+ assertTrue(p.getRejectedExecutionHandler() instanceof AbortPolicy);
}
}
@@ -497,8 +504,8 @@
assertFalse(p.awaitTermination(Long.MIN_VALUE, MILLISECONDS));
assertFalse(p.awaitTermination(-1L, NANOSECONDS));
assertFalse(p.awaitTermination(-1L, MILLISECONDS));
- assertFalse(p.awaitTermination(0L, NANOSECONDS));
- assertFalse(p.awaitTermination(0L, MILLISECONDS));
+ assertFalse(p.awaitTermination(randomExpiredTimeout(),
+ randomTimeUnit()));
long timeoutNanos = 999999L;
long startTime = System.nanoTime();
assertFalse(p.awaitTermination(timeoutNanos, NANOSECONDS));
@@ -1079,149 +1086,76 @@
p.submit(task).get();
}});
- await(threadStarted);
+ await(threadStarted); // ensure quiescence
t.interrupt();
awaitTermination(t);
}
}
/**
- * execute throws RejectedExecutionException if saturated.
+ * Submitted tasks are rejected when saturated or shutdown
*/
- public void testSaturatedExecute() {
- final CountDownLatch done = new CountDownLatch(1);
- final ThreadPoolExecutor p =
- new ThreadPoolExecutor(1, 1,
- LONG_DELAY_MS, MILLISECONDS,
- new ArrayBlockingQueue<Runnable>(1));
- try (PoolCleaner cleaner = cleaner(p, done)) {
- Runnable task = new CheckedRunnable() {
- public void realRun() throws InterruptedException {
- await(done);
- }};
- for (int i = 0; i < 2; ++i)
- p.execute(task);
- for (int i = 0; i < 2; ++i) {
- try {
- p.execute(task);
- shouldThrow();
- } catch (RejectedExecutionException success) {}
- assertTrue(p.getTaskCount() <= 2);
- }
- }
- }
-
- /**
- * submit(runnable) throws RejectedExecutionException if saturated.
- */
- public void testSaturatedSubmitRunnable() {
+ public void testSubmittedTasksRejectedWhenSaturatedOrShutdown() throws InterruptedException {
+ final ThreadPoolExecutor p = new ThreadPoolExecutor(
+ 1, 1, 1, SECONDS, new ArrayBlockingQueue<Runnable>(1));
+ final int saturatedSize = saturatedSize(p);
+ final ThreadLocalRandom rnd = ThreadLocalRandom.current();
+ final CountDownLatch threadsStarted = new CountDownLatch(p.getMaximumPoolSize());
final CountDownLatch done = new CountDownLatch(1);
- final ThreadPoolExecutor p =
- new ThreadPoolExecutor(1, 1,
- LONG_DELAY_MS, MILLISECONDS,
- new ArrayBlockingQueue<Runnable>(1));
- try (PoolCleaner cleaner = cleaner(p, done)) {
- Runnable task = new CheckedRunnable() {
- public void realRun() throws InterruptedException {
- await(done);
- }};
- for (int i = 0; i < 2; ++i)
- p.submit(task);
- for (int i = 0; i < 2; ++i) {
+ final Runnable r = () -> {
+ threadsStarted.countDown();
+ for (;;) {
try {
- p.execute(task);
- shouldThrow();
- } catch (RejectedExecutionException success) {}
- assertTrue(p.getTaskCount() <= 2);
- }
- }
- }
+ done.await();
+ return;
+ } catch (InterruptedException shutdownNowDeliberatelyIgnored) {}
+ }};
+ final Callable<Boolean> c = () -> {
+ threadsStarted.countDown();
+ for (;;) {
+ try {
+ done.await();
+ return Boolean.TRUE;
+ } catch (InterruptedException shutdownNowDeliberatelyIgnored) {}
+ }};
+ final boolean shutdownNow = rnd.nextBoolean();
- /**
- * submit(callable) throws RejectedExecutionException if saturated.
- */
- public void testSaturatedSubmitCallable() {
- final CountDownLatch done = new CountDownLatch(1);
- final ThreadPoolExecutor p =
- new ThreadPoolExecutor(1, 1,
- LONG_DELAY_MS, MILLISECONDS,
- new ArrayBlockingQueue<Runnable>(1));
try (PoolCleaner cleaner = cleaner(p, done)) {
- Runnable task = new CheckedRunnable() {
- public void realRun() throws InterruptedException {
- await(done);
- }};
- for (int i = 0; i < 2; ++i)
- p.execute(task);
- for (int i = 0; i < 2; ++i) {
- try {
- p.execute(task);
- shouldThrow();
- } catch (RejectedExecutionException success) {}
- assertTrue(p.getTaskCount() <= 2);
+ // saturate
+ for (int i = saturatedSize; i--> 0; ) {
+ switch (rnd.nextInt(4)) {
+ case 0: p.execute(r); break;
+ case 1: assertFalse(p.submit(r).isDone()); break;
+ case 2: assertFalse(p.submit(r, Boolean.TRUE).isDone()); break;
+ case 3: assertFalse(p.submit(c).isDone()); break;
+ }
}
- }
- }
+
+ await(threadsStarted);
+ assertTaskSubmissionsAreRejected(p);
- /**
- * executor using CallerRunsPolicy runs task if saturated.
- */
- public void testSaturatedExecute2() {
- final ThreadPoolExecutor p =
- new ThreadPoolExecutor(1, 1,
- LONG_DELAY_MS,
- MILLISECONDS,
- new ArrayBlockingQueue<Runnable>(1),
- new ThreadPoolExecutor.CallerRunsPolicy());
- try (PoolCleaner cleaner = cleaner(p)) {
- final CountDownLatch done = new CountDownLatch(1);
- Runnable blocker = new CheckedRunnable() {
- public void realRun() throws InterruptedException {
- await(done);
- }};
- p.execute(blocker);
- TrackedNoOpRunnable[] tasks = new TrackedNoOpRunnable[5];
- for (int i = 0; i < tasks.length; i++)
- tasks[i] = new TrackedNoOpRunnable();
- for (int i = 0; i < tasks.length; i++)
- p.execute(tasks[i]);
- for (int i = 1; i < tasks.length; i++)
- assertTrue(tasks[i].done);
- assertFalse(tasks[0].done); // waiting in queue
- done.countDown();
+ if (shutdownNow)
+ p.shutdownNow();
+ else
+ p.shutdown();
+ // Pool is shutdown, but not yet terminated
+ assertTaskSubmissionsAreRejected(p);
+ assertFalse(p.isTerminated());
+
+ done.countDown(); // release blocking tasks
+ assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
+
+ assertTaskSubmissionsAreRejected(p);
}
- }
-
- /**
- * executor using DiscardPolicy drops task if saturated.
- */
- public void testSaturatedExecute3() {
- final CountDownLatch done = new CountDownLatch(1);
- final TrackedNoOpRunnable[] tasks = new TrackedNoOpRunnable[5];
- for (int i = 0; i < tasks.length; ++i)
- tasks[i] = new TrackedNoOpRunnable();
- final ThreadPoolExecutor p =
- new ThreadPoolExecutor(1, 1,
- LONG_DELAY_MS, MILLISECONDS,
- new ArrayBlockingQueue<Runnable>(1),
- new ThreadPoolExecutor.DiscardPolicy());
- try (PoolCleaner cleaner = cleaner(p, done)) {
- p.execute(awaiter(done));
-
- for (TrackedNoOpRunnable task : tasks)
- p.execute(task);
- for (int i = 1; i < tasks.length; i++)
- assertFalse(tasks[i].done);
- }
- for (int i = 1; i < tasks.length; i++)
- assertFalse(tasks[i].done);
- assertTrue(tasks[0].done); // was waiting in queue
+ assertEquals(saturatedSize(p)
+ - (shutdownNow ? p.getQueue().remainingCapacity() : 0),
+ p.getCompletedTaskCount());
}
/**
* executor using DiscardOldestPolicy drops oldest task if saturated.
*/
- public void testSaturatedExecute4() {
+ public void testSaturatedExecute_DiscardOldestPolicy() {
final CountDownLatch done = new CountDownLatch(1);
LatchAwaiter r1 = awaiter(done);
LatchAwaiter r2 = awaiter(done);
@@ -1230,7 +1164,7 @@
new ThreadPoolExecutor(1, 1,
LONG_DELAY_MS, MILLISECONDS,
new ArrayBlockingQueue<Runnable>(1),
- new ThreadPoolExecutor.DiscardOldestPolicy());
+ new DiscardOldestPolicy());
try (PoolCleaner cleaner = cleaner(p, done)) {
assertEquals(LatchAwaiter.NEW, r1.state);
assertEquals(LatchAwaiter.NEW, r2.state);
@@ -1248,31 +1182,14 @@
}
/**
- * execute throws RejectedExecutionException if shutdown
+ * execute using DiscardOldestPolicy drops task on shutdown
*/
- public void testRejectedExecutionExceptionOnShutdown() {
+ public void testDiscardOldestOnShutdown() {
final ThreadPoolExecutor p =
new ThreadPoolExecutor(1, 1,
LONG_DELAY_MS, MILLISECONDS,
- new ArrayBlockingQueue<Runnable>(1));
- try { p.shutdown(); } catch (SecurityException ok) { return; }
- try (PoolCleaner cleaner = cleaner(p)) {
- try {
- p.execute(new NoOpRunnable());
- shouldThrow();
- } catch (RejectedExecutionException success) {}
- }
- }
-
- /**
- * execute using CallerRunsPolicy drops task on shutdown
- */
- public void testCallerRunsOnShutdown() {
- RejectedExecutionHandler h = new ThreadPoolExecutor.CallerRunsPolicy();
- final ThreadPoolExecutor p =
- new ThreadPoolExecutor(1, 1,
- LONG_DELAY_MS, MILLISECONDS,
- new ArrayBlockingQueue<Runnable>(1), h);
+ new ArrayBlockingQueue<Runnable>(1),
+ new DiscardOldestPolicy());
try { p.shutdown(); } catch (SecurityException ok) { return; }
try (PoolCleaner cleaner = cleaner(p)) {
@@ -1283,54 +1200,15 @@
}
/**
- * execute using DiscardPolicy drops task on shutdown
- */
- public void testDiscardOnShutdown() {
- final ThreadPoolExecutor p =
- new ThreadPoolExecutor(1, 1,
- LONG_DELAY_MS, MILLISECONDS,
- new ArrayBlockingQueue<Runnable>(1),
- new ThreadPoolExecutor.DiscardPolicy());
-
- try { p.shutdown(); } catch (SecurityException ok) { return; }
- try (PoolCleaner cleaner = cleaner(p)) {
- TrackedNoOpRunnable r = new TrackedNoOpRunnable();
- p.execute(r);
- assertFalse(r.done);
- }
- }
-
- /**
- * execute using DiscardOldestPolicy drops task on shutdown
+ * Submitting null tasks throws NullPointerException
*/
- public void testDiscardOldestOnShutdown() {
- final ThreadPoolExecutor p =
- new ThreadPoolExecutor(1, 1,
- LONG_DELAY_MS, MILLISECONDS,
- new ArrayBlockingQueue<Runnable>(1),
- new ThreadPoolExecutor.DiscardOldestPolicy());
-
- try { p.shutdown(); } catch (SecurityException ok) { return; }
- try (PoolCleaner cleaner = cleaner(p)) {
- TrackedNoOpRunnable r = new TrackedNoOpRunnable();
- p.execute(r);
- assertFalse(r.done);
- }
- }
-
- /**
- * execute(null) throws NPE
- */
- public void testExecuteNull() {
+ public void testNullTaskSubmission() {
final ThreadPoolExecutor p =
new ThreadPoolExecutor(1, 2,
1L, SECONDS,
new ArrayBlockingQueue<Runnable>(10));
try (PoolCleaner cleaner = cleaner(p)) {
- try {
- p.execute(null);
- shouldThrow();
- } catch (NullPointerException success) {}
+ assertNullTaskSubmissionThrowsNullPointerException(p);
}
}
@@ -1522,7 +1400,7 @@
}
/**
- * invokeAny(empty collection) throws IAE
+ * invokeAny(empty collection) throws IllegalArgumentException
*/
public void testInvokeAny2() throws Exception {
final ExecutorService e =
@@ -1612,15 +1490,17 @@
}
/**
- * invokeAll(empty collection) returns empty collection
+ * invokeAll(empty collection) returns empty list
*/
public void testInvokeAll2() throws InterruptedException {
final ExecutorService e =
new ThreadPoolExecutor(2, 2,
LONG_DELAY_MS, MILLISECONDS,
new ArrayBlockingQueue<Runnable>(10));
+ final Collection<Callable<String>> emptyCollection
+ = Collections.emptyList();
try (PoolCleaner cleaner = cleaner(e)) {
- List<Future<String>> r = e.invokeAll(new ArrayList<Callable<String>>());
+ List<Future<String>> r = e.invokeAll(emptyCollection);
assertTrue(r.isEmpty());
}
}
@@ -1695,7 +1575,7 @@
new ArrayBlockingQueue<Runnable>(10));
try (PoolCleaner cleaner = cleaner(e)) {
try {
- e.invokeAny(null, MEDIUM_DELAY_MS, MILLISECONDS);
+ e.invokeAny(null, randomTimeout(), randomTimeUnit());
shouldThrow();
} catch (NullPointerException success) {}
}
@@ -1713,14 +1593,14 @@
List<Callable<String>> l = new ArrayList<>();
l.add(new StringTask());
try {
- e.invokeAny(l, MEDIUM_DELAY_MS, null);
+ e.invokeAny(l, randomTimeout(), null);
shouldThrow();
} catch (NullPointerException success) {}
}
}
/**
- * timed invokeAny(empty collection) throws IAE
+ * timed invokeAny(empty collection) throws IllegalArgumentException
*/
public void testTimedInvokeAny2() throws Exception {
final ExecutorService e =
@@ -1730,14 +1610,14 @@
try (PoolCleaner cleaner = cleaner(e)) {
try {
e.invokeAny(new ArrayList<Callable<String>>(),
- MEDIUM_DELAY_MS, MILLISECONDS);
+ randomTimeout(), randomTimeUnit());
shouldThrow();
} catch (IllegalArgumentException success) {}
}
}
/**
- * timed invokeAny(c) throws NPE if c has null elements
+ * timed invokeAny(c) throws NullPointerException if c has null elements
*/
public void testTimedInvokeAny3() throws Exception {
final CountDownLatch latch = new CountDownLatch(1);
@@ -1750,7 +1630,7 @@
l.add(latchAwaitingStringTask(latch));
l.add(null);
try {
- e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
+ e.invokeAny(l, randomTimeout(), randomTimeUnit());
shouldThrow();
} catch (NullPointerException success) {}
latch.countDown();
@@ -1808,7 +1688,7 @@
new ArrayBlockingQueue<Runnable>(10));
try (PoolCleaner cleaner = cleaner(e)) {
try {
- e.invokeAll(null, MEDIUM_DELAY_MS, MILLISECONDS);
+ e.invokeAll(null, randomTimeout(), randomTimeUnit());
shouldThrow();
} catch (NullPointerException success) {}
}
@@ -1826,23 +1706,25 @@
List<Callable<String>> l = new ArrayList<>();
l.add(new StringTask());
try {
- e.invokeAll(l, MEDIUM_DELAY_MS, null);
+ e.invokeAll(l, randomTimeout(), null);
shouldThrow();
} catch (NullPointerException success) {}
}
}
/**
- * timed invokeAll(empty collection) returns empty collection
+ * timed invokeAll(empty collection) returns empty list
*/
public void testTimedInvokeAll2() throws InterruptedException {
final ExecutorService e =
new ThreadPoolExecutor(2, 2,
LONG_DELAY_MS, MILLISECONDS,
new ArrayBlockingQueue<Runnable>(10));
+ final Collection<Callable<String>> emptyCollection
+ = Collections.emptyList();
try (PoolCleaner cleaner = cleaner(e)) {
- List<Future<String>> r = e.invokeAll(new ArrayList<Callable<String>>(),
- MEDIUM_DELAY_MS, MILLISECONDS);
+ List<Future<String>> r =
+ e.invokeAll(emptyCollection, randomTimeout(), randomTimeUnit());
assertTrue(r.isEmpty());
}
}
@@ -1860,7 +1742,7 @@
l.add(new StringTask());
l.add(null);
try {
- e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
+ e.invokeAll(l, randomTimeout(), randomTimeUnit());
shouldThrow();
} catch (NullPointerException success) {}
}
@@ -2102,4 +1984,31 @@
}
}
+ /** Directly test simple ThreadPoolExecutor RejectedExecutionHandlers. */
+ public void testStandardRejectedExecutionHandlers() {
+ final ThreadPoolExecutor p =
+ new ThreadPoolExecutor(1, 1, 1, SECONDS,
+ new ArrayBlockingQueue<Runnable>(1));
+ final AtomicReference<Thread> thread = new AtomicReference<>();
+ final Runnable r = new Runnable() { public void run() {
+ thread.set(Thread.currentThread()); }};
+
+ try {
+ new AbortPolicy().rejectedExecution(r, p);
+ shouldThrow();
+ } catch (RejectedExecutionException success) {}
+ assertNull(thread.get());
+
+ new DiscardPolicy().rejectedExecution(r, p);
+ assertNull(thread.get());
+
+ new CallerRunsPolicy().rejectedExecution(r, p);
+ assertSame(Thread.currentThread(), thread.get());
+
+ // check that pool was not perturbed by handlers
+ assertTrue(p.getRejectedExecutionHandler() instanceof AbortPolicy);
+ assertEquals(0, p.getTaskCount());
+ assertTrue(p.getQueue().isEmpty());
+ }
+
}
--- a/jdk/test/java/util/concurrent/tck/TimeUnitTest.java Mon Jul 24 11:54:57 2017 +0530
+++ b/jdk/test/java/util/concurrent/tck/TimeUnitTest.java Tue Jul 25 14:07:37 2017 -0700
@@ -553,7 +553,7 @@
}});
await(pleaseInterrupt);
- assertThreadStaysAlive(t);
+ assertThreadBlocks(t, Thread.State.TIMED_WAITING);
t.interrupt();
awaitTermination(t);
}
@@ -586,7 +586,7 @@
}});
await(pleaseInterrupt);
- assertThreadStaysAlive(t);
+ assertThreadBlocks(t, Thread.State.TIMED_WAITING);
t.interrupt();
awaitTermination(t);
s.interrupt();
@@ -617,7 +617,7 @@
}});
await(pleaseInterrupt);
- assertThreadStaysAlive(t);
+ assertThreadBlocks(t, Thread.State.TIMED_WAITING);
t.interrupt();
awaitTermination(t);
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/provider/DSA/TestMaxLengthDER.java Tue Jul 25 14:07:37 2017 -0700
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8183591
+ * @summary Test decoding of DER length fields containing Integer.MAX_VALUE
+ * @run main TestMaxLengthDER
+ */
+
+import java.io.*;
+import java.math.*;
+import java.security.*;
+import java.security.spec.*;
+
+public class TestMaxLengthDER {
+
+ public static void main(String[] args) throws Exception {
+
+ String message = "Message";
+ Signature sig = Signature.getInstance("SHA256withDSA");
+ KeyPairGenerator kpg = KeyPairGenerator.getInstance("DSA");
+ SecureRandom rnd = new SecureRandom();
+ rnd.setSeed(1);
+ kpg.initialize(2048, rnd);
+ KeyPair kp = kpg.generateKeyPair();
+ sig.initSign(kp.getPrivate());
+ sig.update(message.getBytes());
+ byte[] sigData = sig.sign();
+
+ // Set the length of the second integer to Integer.MAX_VALUE
+ // First copy all the signature data to the correct location
+ int lengthPos = sigData[3] + 5;
+ byte[] modifiedSigData = new byte[sigData.length + 4];
+ System.arraycopy(sigData, 0, modifiedSigData, 0, lengthPos);
+ System.arraycopy(sigData, lengthPos + 1, modifiedSigData,
+ lengthPos + 5, sigData.length - (lengthPos + 1));
+
+ // Increase the length (in bytes) of the sequence to account for
+ // the larger length field
+ modifiedSigData[1] += 4;
+
+ // Modify the length field
+ modifiedSigData[lengthPos] = (byte) 0x84;
+ modifiedSigData[lengthPos + 1] = (byte) 0x7F;
+ modifiedSigData[lengthPos + 2] = (byte) 0xFF;
+ modifiedSigData[lengthPos + 3] = (byte) 0xFF;
+ modifiedSigData[lengthPos + 4] = (byte) 0xFF;
+
+ sig.initVerify(kp.getPublic());
+ sig.update(message.getBytes());
+
+ try {
+ sig.verify(modifiedSigData);
+ throw new RuntimeException("No exception on misencoded signature");
+ } catch (SignatureException ex) {
+ if (ex.getCause() instanceof EOFException) {
+ // this is expected
+ } else {
+ throw ex;
+ }
+ }
+ }
+}
--- a/jdk/test/sun/security/util/DerValue/BadValue.java Mon Jul 24 11:54:57 2017 +0530
+++ b/jdk/test/sun/security/util/DerValue/BadValue.java Tue Jul 25 14:07:37 2017 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2017 Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -48,30 +48,37 @@
if (bs.length != 6 || in.available() != 0) {
throw new Exception("Second read error");
}
- // MAX read as much as it can
+ // MAX length results in exception
in = new ByteArrayInputStream(new byte[10]);
- bs = IOUtils.readFully(in, Integer.MAX_VALUE, true);
- if (bs.length != 10 || in.available() != 0) {
- throw new Exception("Second read error");
+ try {
+ bs = IOUtils.readFully(in, Integer.MAX_VALUE, true);
+ throw new Exception("No exception on MAX_VALUE length");
+ } catch (EOFException ex) {
+ // this is expected
+ } catch (IOException ex) {
+ throw ex;
}
- // MAX ignore readAll
+ // -1 length results in exception
in = new ByteArrayInputStream(new byte[10]);
- bs = IOUtils.readFully(in, Integer.MAX_VALUE, false);
- if (bs.length != 10 || in.available() != 0) {
- throw new Exception("Second read error");
+ try {
+ bs = IOUtils.readFully(in, -1, true);
+ throw new Exception("No exception on -1 length");
+ } catch (IOException ex) {
+ // this is expected
}
+
// 20>10, readAll means failure
in = new ByteArrayInputStream(new byte[10]);
try {
bs = IOUtils.readFully(in, 20, true);
- throw new Exception("Third read error");
+ throw new Exception("No exception on EOF");
} catch (EOFException e) {
// OK
}
int bignum = 10 * 1024 * 1024;
- bs = IOUtils.readFully(new SuperSlowStream(bignum), -1, true);
+ bs = IOUtils.readFully(new SuperSlowStream(bignum), bignum, true);
if (bs.length != bignum) {
- throw new Exception("Fourth read error");
+ throw new Exception("Read returned small array");
}
// Test DerValue