This commit is contained in:
Phil Race 2017-07-27 12:36:49 -07:00
commit 2f5f248880
148 changed files with 2395 additions and 2272 deletions

View File

@ -437,3 +437,4 @@ e6d70017f5b9adbb2ec82d826973d0251800a3c3 jdk-10+12
9927a9f16738e240ab7014f0118f41e314ef8f99 jdk-10+13 9927a9f16738e240ab7014f0118f41e314ef8f99 jdk-10+13
9ef5029b247b4d940080417a287440bbdbab995b jdk-10+14 9ef5029b247b4d940080417a287440bbdbab995b jdk-10+14
878e216039322cb3f0ecbd0944642a2b4e2593f3 jdk-10+15 878e216039322cb3f0ecbd0944642a2b4e2593f3 jdk-10+15
4bbea012e5676e8025ade2bcfab4d6581e6e9f4b jdk-10+16

View File

@ -437,3 +437,5 @@ d67a3f1f057f7e31e12f33ebe3667cb73d252268 jdk-10+13
a4371edb589c60db01142e45c317adb9ccbcb083 jdk-9+177 a4371edb589c60db01142e45c317adb9ccbcb083 jdk-9+177
a6c830ee8a6798b186730475e700027cdf4598aa jdk-10+15 a6c830ee8a6798b186730475e700027cdf4598aa jdk-10+15
2fe66ca1e2b3c361f949de9cb2894661dc0a3fa2 jdk-10+16 2fe66ca1e2b3c361f949de9cb2894661dc0a3fa2 jdk-10+16
ec4159ebe7050fcc5dcee8a2d150cf948ecc97db jdk-9+178
252475ccfd84cc249f8d6faf4b7806b5e2c384ce jdk-9+179

View File

@ -436,3 +436,4 @@ dc78a3dd6b3a4f11cdae8a3e3d160e6a78bc7838 jdk-9+175
40fb9f229471ef357d493813d34b15afcce9f32b jdk-9+176 40fb9f229471ef357d493813d34b15afcce9f32b jdk-9+176
c72e9d3823f04cb3ef3166646dfea9e4c2769133 jdk-9+177 c72e9d3823f04cb3ef3166646dfea9e4c2769133 jdk-9+177
15f59cfc6fbe9387423fb173e962265c7b5d357e jdk-10+15 15f59cfc6fbe9387423fb173e962265c7b5d357e jdk-10+15
b82b62ed5debda2d98dda597506ef29cf947fbae jdk-10+16

View File

@ -596,3 +596,4 @@ e920b4d008d914f3414bd4630b58837cf0b7f08d jdk-10+14
2ab74e5dbdc2b6a962c865500cafd23cf387dc60 jdk-9+176 2ab74e5dbdc2b6a962c865500cafd23cf387dc60 jdk-9+176
1ca8f038fceb88c640badf9bd18905205bc63b43 jdk-9+177 1ca8f038fceb88c640badf9bd18905205bc63b43 jdk-9+177
c1f3649a3a42f124b418a5a916dbad13d059b757 jdk-10+15 c1f3649a3a42f124b418a5a916dbad13d059b757 jdk-10+15
2fe2a593e8ebf3a9e4dcd9ba3333a7b43126589d jdk-10+16

View File

@ -436,3 +436,4 @@ ff293e39e83366c40a5687dacd1ccb2305ed2c1e jdk-10+12
38cf34e2328070cc691c4f136e6dde1a44c04171 jdk-9+176 38cf34e2328070cc691c4f136e6dde1a44c04171 jdk-9+176
332ad9f92632f56f337b8c40edef9a95a42b26bc jdk-9+177 332ad9f92632f56f337b8c40edef9a95a42b26bc jdk-9+177
02a876781a3a6193140591d92db7b95ca743eac2 jdk-10+15 02a876781a3a6193140591d92db7b95ca743eac2 jdk-10+15
d109d55cf642bf2b438624e81f94c18c168f9178 jdk-10+16

View File

@ -439,3 +439,4 @@ bddeaa49ffd55567ad232548c38aa270e1a1420a jdk-10+14
ea819b6009d33a72e6672bab6c101d51db0cfb4c jdk-9+176 ea819b6009d33a72e6672bab6c101d51db0cfb4c jdk-9+176
b44a721aee3d3b2537754e559fe9ecccadea548b jdk-9+177 b44a721aee3d3b2537754e559fe9ecccadea548b jdk-9+177
6d17fd0a5133a0dd916c77a9a24ae7f0ca402876 jdk-10+15 6d17fd0a5133a0dd916c77a9a24ae7f0ca402876 jdk-10+15
bc8289ce1ed3ed5fff62152ed46da3be0b60b7c3 jdk-10+16

View File

@ -112,7 +112,7 @@ public class CommandInfo {
* this method will check if it implements the * this method will check if it implements the
* java.io.Externalizable interface. If it does, the bean's * java.io.Externalizable interface. If it does, the bean's
* readExternal method will be called if an InputStream * readExternal method will be called if an InputStream
* can be acquired from the DataHandler.<p> * can be acquired from the DataHandler.
* *
* @param dh The DataHandler that describes the data to be * @param dh The DataHandler that describes the data to be
* passed to the command. * passed to the command.

View File

@ -436,3 +436,4 @@ e6c4f6ef717d104dba880e2dae538690c993b46f jdk-9+175
9f27d513658d5375b0e26846857d92563f279073 jdk-9+176 9f27d513658d5375b0e26846857d92563f279073 jdk-9+176
80acf577b7d0b886fb555c9916552844f6cc72af jdk-9+177 80acf577b7d0b886fb555c9916552844f6cc72af jdk-9+177
e069834e2c518a7bc2ffadc8c7e3cd7ec69fa8a0 jdk-10+15 e069834e2c518a7bc2ffadc8c7e3cd7ec69fa8a0 jdk-10+15
3281b964ab104002623d744e8b77a12269b70acd jdk-10+16

View File

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -1378,7 +1378,7 @@ JDWP "Java(tm) Debug Wire Protocol"
(Repeat lines "The number of entries in the line table for this method." (Repeat lines "The number of entries in the line table for this method."
(Group LineInfo (Group LineInfo
(long lineCodeIndex "Initial code index of the line, " (long lineCodeIndex "Initial code index of the line, "
"start <= lineCodeIndex < end") "start &lt;= lineCodeIndex &lt; end")
(int lineNumber "Line number.") (int lineNumber "Line number.")
) )
) )
@ -1409,13 +1409,13 @@ JDWP "Java(tm) Debug Wire Protocol"
"First code index at which the variable is visible (unsigned). " "First code index at which the variable is visible (unsigned). "
"Used in conjunction with <code>length</code>. " "Used in conjunction with <code>length</code>. "
"The variable can be get or set only when the current " "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> &lt;= current frame code index &lt; <code>codeIndex + length</code> ")
(string name "The variable's name.") (string name "The variable's name.")
(string signature "The variable type's JNI signature.") (string signature "The variable type's JNI signature.")
(int length (int length
"Unsigned value used in conjunction with <code>codeIndex</code>. " "Unsigned value used in conjunction with <code>codeIndex</code>. "
"The variable can be get or set only when the current " "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> &lt;= current frame code index &lt; <code>code index + length</code> ")
(int slot "The local variable's index in its frame") (int slot "The local variable's index in its frame")
) )
) )
@ -1502,7 +1502,7 @@ JDWP "Java(tm) Debug Wire Protocol"
"First code index at which the variable is visible (unsigned). " "First code index at which the variable is visible (unsigned). "
"Used in conjunction with <code>length</code>. " "Used in conjunction with <code>length</code>. "
"The variable can be get or set only when the current " "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> &lt;= current frame code index &lt; <code>codeIndex + length</code> ")
(string name "The variable's name.") (string name "The variable's name.")
(string signature "The variable type's JNI signature.") (string signature "The variable type's JNI signature.")
(string genericSignature "The variable type's generic " (string genericSignature "The variable type's generic "
@ -1510,7 +1510,7 @@ JDWP "Java(tm) Debug Wire Protocol"
(int length (int length
"Unsigned value used in conjunction with <code>codeIndex</code>. " "Unsigned value used in conjunction with <code>codeIndex</code>. "
"The variable can be get or set only when the current " "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> &lt;= current frame code index &lt; <code>code index + length</code> ")
(int slot "The local variable's index in its frame") (int slot "The local variable's index in its frame")
) )
) )

View File

@ -1960,10 +1960,6 @@ public final class System {
setOut0(newPrintStream(fdOut, props.getProperty("sun.stdout.encoding"))); setOut0(newPrintStream(fdOut, props.getProperty("sun.stdout.encoding")));
setErr0(newPrintStream(fdErr, props.getProperty("sun.stderr.encoding"))); setErr0(newPrintStream(fdErr, props.getProperty("sun.stderr.encoding")));
// Load the zip library now in order to keep java.util.zip.ZipFile
// from trying to use itself to load this library later.
loadLibrary("zip");
// Setup Java signal handlers for HUP, TERM, and INT (where available). // Setup Java signal handlers for HUP, TERM, and INT (where available).
Terminator.setup(); Terminator.setup();

View File

@ -243,7 +243,7 @@ public class ArrayDeque<E> extends AbstractCollection<E>
* Index i must be logically ahead of index j. * Index i must be logically ahead of index j.
* Precondition: 0 <= i < modulus, 0 <= j < modulus. * Precondition: 0 <= i < modulus, 0 <= j < modulus.
* @return the "circular distance" from j to i; corner case i == j * @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) { static final int sub(int i, int j, int modulus) {
if ((i -= j) < 0) i += modulus; if ((i -= j) < 0) i += modulus;
@ -310,8 +310,7 @@ public class ArrayDeque<E> extends AbstractCollection<E>
/** /**
* Adds all of the elements in the specified collection at the end * Adds all of the elements in the specified collection at the end
* of this deque, as if by calling {@link #addLast} on each one, * of this deque, as if by calling {@link #addLast} on each one,
* in the order that they are returned by the collection's * in the order that they are returned by the collection's iterator.
* iterator.
* *
* @param c the elements to be inserted into this deque * @param c the elements to be inserted into this deque
* @return {@code true} if this deque changed as a result of the call * @return {@code true} if this deque changed as a result of the call
@ -508,8 +507,8 @@ public class ArrayDeque<E> extends AbstractCollection<E>
/** /**
* Retrieves and removes the head of the queue represented by this deque. * 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
* exception if this deque is empty. * throws an exception if this deque is empty.
* *
* <p>This method is equivalent to {@link #removeFirst}. * <p>This method is equivalent to {@link #removeFirst}.
* *

View File

@ -514,15 +514,10 @@ public class ArrayList<E> extends AbstractList<E>
*/ */
public E remove(int index) { public E remove(int index) {
Objects.checkIndex(index, size); Objects.checkIndex(index, size);
final Object[] es = elementData;
modCount++; @SuppressWarnings("unchecked") E oldValue = (E) es[index];
E oldValue = elementData(index); fastRemove(es, index);
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
return oldValue; return oldValue;
} }
@ -541,33 +536,35 @@ public class ArrayList<E> extends AbstractList<E>
* @return {@code true} if this list contained the specified element * @return {@code true} if this list contained the specified element
*/ */
public boolean remove(Object o) { public boolean remove(Object o) {
if (o == null) { final Object[] es = elementData;
for (int index = 0; index < size; index++) final int size = this.size;
if (elementData[index] == null) { int i = 0;
fastRemove(index); found: {
return true; if (o == null) {
} for (; i < size; i++)
} else { if (es[i] == null)
for (int index = 0; index < size; index++) break found;
if (o.equals(elementData[index])) { } else {
fastRemove(index); for (; i < size; i++)
return true; 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 * Private remove method that skips bounds checking and does not
* return the value removed. * return the value removed.
*/ */
private void fastRemove(int index) { private void fastRemove(Object[] es, int i) {
modCount++; modCount++;
int numMoved = size - index - 1; final int newSize;
if (numMoved > 0) if ((newSize = size - 1) > i)
System.arraycopy(elementData, index+1, elementData, index, System.arraycopy(es, i + 1, es, i, newSize - i);
numMoved); es[size = newSize] = null;
elementData[--size] = null; // clear to let GC do its work
} }
/** /**
@ -743,29 +740,30 @@ public class ArrayList<E> extends AbstractList<E>
final int from, final int end) { final int from, final int end) {
Objects.requireNonNull(c); Objects.requireNonNull(c);
final Object[] es = elementData; final Object[] es = elementData;
final boolean modified;
int r; int r;
// Optimize for initial run of survivors // Optimize for initial run of survivors
for (r = from; r < end && c.contains(es[r]) == complement; r++) for (r = from;; r++) {
; if (r == end)
if (modified = (r < end)) { return false;
int w = r++; if (c.contains(es[r]) != complement)
try { break;
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 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 @@ public class ArrayList<E> extends AbstractList<E>
int expectedModCount = modCount; int expectedModCount = modCount;
s.defaultWriteObject(); 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); s.writeInt(size);
// Write out all elements in the proper order. // Write out all elements in the proper order.

View File

@ -37,15 +37,14 @@ package java.util;
/** /**
* A collection designed for holding elements prior to processing. * A collection designed for holding elements prior to processing.
* Besides basic {@link java.util.Collection Collection} operations, * Besides basic {@link Collection} operations, queues provide
* queues provide additional insertion, extraction, and inspection * additional insertion, extraction, and inspection operations.
* operations. Each of these methods exists in two forms: one throws * Each of these methods exists in two forms: one throws an exception
* an exception if the operation fails, the other returns a special * if the operation fails, the other returns a special value (either
* value (either {@code null} or {@code false}, depending on the * {@code null} or {@code false}, depending on the operation). The
* operation). The latter form of the insert operation is designed * latter form of the insert operation is designed specifically for
* specifically for use with capacity-restricted {@code Queue} * use with capacity-restricted {@code Queue} implementations; in most
* implementations; in most implementations, insert operations cannot * implementations, insert operations cannot fail.
* fail.
* *
* <table class="plain"> * <table class="plain">
* <caption>Summary of Queue methods</caption> * <caption>Summary of Queue methods</caption>
@ -56,18 +55,18 @@ package java.util;
* </tr> * </tr>
* <tr> * <tr>
* <td><b>Insert</b></td> * <td><b>Insert</b></td>
* <td>{@link Queue#add add(e)}</td> * <td>{@link #add(Object) add(e)}</td>
* <td>{@link Queue#offer offer(e)}</td> * <td>{@link #offer(Object) offer(e)}</td>
* </tr> * </tr>
* <tr> * <tr>
* <td><b>Remove</b></td> * <td><b>Remove</b></td>
* <td>{@link Queue#remove remove()}</td> * <td>{@link #remove() remove()}</td>
* <td>{@link Queue#poll poll()}</td> * <td>{@link #poll() poll()}</td>
* </tr> * </tr>
* <tr> * <tr>
* <td><b>Examine</b></td> * <td><b>Examine</b></td>
* <td>{@link Queue#element element()}</td> * <td>{@link #element() element()}</td>
* <td>{@link Queue#peek peek()}</td> * <td>{@link #peek() peek()}</td>
* </tr> * </tr>
* </table> * </table>
* *
@ -77,7 +76,7 @@ package java.util;
* comparator, or the elements' natural ordering, and LIFO queues (or * comparator, or the elements' natural ordering, and LIFO queues (or
* stacks) which order the elements LIFO (last-in-first-out). * stacks) which order the elements LIFO (last-in-first-out).
* Whatever the ordering used, the <em>head</em> of the queue is that * 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 * {@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 * the <em>tail</em> of the queue. Other kinds of queues may use
* different placement rules. Every {@code Queue} implementation * different placement rules. Every {@code Queue} implementation
@ -173,8 +172,8 @@ public interface Queue<E> extends Collection<E> {
/** /**
* Retrieves and removes the head of this queue. This method differs * Retrieves and removes the head of this queue. This method differs
* from {@link #poll poll} only in that it throws an exception if this * from {@link #poll() poll()} only in that it throws an exception if
* queue is empty. * this queue is empty.
* *
* @return the head of this queue * @return the head of this queue
* @throws NoSuchElementException if this queue is empty * @throws NoSuchElementException if this queue is empty

View File

@ -67,22 +67,22 @@ import java.util.NoSuchElementException;
* </tr> * </tr>
* <tr> * <tr>
* <td><b>Insert</b></td> * <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 #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> * <td>{@link #offerFirst(Object, long, TimeUnit) offerFirst(e, time, unit)}</td>
* </tr> * </tr>
* <tr> * <tr>
* <td><b>Remove</b></td> * <td><b>Remove</b></td>
* <td>{@link #removeFirst removeFirst()}</td> * <td>{@link #removeFirst() removeFirst()}</td>
* <td>{@link #pollFirst pollFirst()}</td> * <td>{@link #pollFirst() pollFirst()}</td>
* <td>{@link #takeFirst takeFirst()}</td> * <td>{@link #takeFirst() takeFirst()}</td>
* <td>{@link #pollFirst(long, TimeUnit) pollFirst(time, unit)}</td> * <td>{@link #pollFirst(long, TimeUnit) pollFirst(time, unit)}</td>
* </tr> * </tr>
* <tr> * <tr>
* <td><b>Examine</b></td> * <td><b>Examine</b></td>
* <td>{@link #getFirst getFirst()}</td> * <td>{@link #getFirst() getFirst()}</td>
* <td>{@link #peekFirst peekFirst()}</td> * <td>{@link #peekFirst() peekFirst()}</td>
* <td><em>not applicable</em></td> * <td><em>not applicable</em></td>
* <td><em>not applicable</em></td> * <td><em>not applicable</em></td>
* </tr> * </tr>
@ -98,22 +98,22 @@ import java.util.NoSuchElementException;
* </tr> * </tr>
* <tr> * <tr>
* <td><b>Insert</b></td> * <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 #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> * <td>{@link #offerLast(Object, long, TimeUnit) offerLast(e, time, unit)}</td>
* </tr> * </tr>
* <tr> * <tr>
* <td><b>Remove</b></td> * <td><b>Remove</b></td>
* <td>{@link #removeLast() removeLast()}</td> * <td>{@link #removeLast() removeLast()}</td>
* <td>{@link #pollLast() pollLast()}</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> * <td>{@link #pollLast(long, TimeUnit) pollLast(time, unit)}</td>
* </tr> * </tr>
* <tr> * <tr>
* <td><b>Examine</b></td> * <td><b>Examine</b></td>
* <td>{@link #getLast getLast()}</td> * <td>{@link #getLast() getLast()}</td>
* <td>{@link #peekLast peekLast()}</td> * <td>{@link #peekLast() peekLast()}</td>
* <td><em>not applicable</em></td> * <td><em>not applicable</em></td>
* <td><em>not applicable</em></td> * <td><em>not applicable</em></td>
* </tr> * </tr>
@ -512,7 +512,7 @@ public interface BlockingDeque<E> extends BlockingQueue<E>, Deque<E> {
/** /**
* Retrieves and removes the head of the queue represented by this deque * Retrieves and removes the head of the queue represented by this deque
* (in other words, the first element of 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. * throws an exception if this deque is empty.
* *
* <p>This method is equivalent to {@link #removeFirst() removeFirst}. * <p>This method is equivalent to {@link #removeFirst() removeFirst}.
@ -563,7 +563,7 @@ public interface BlockingDeque<E> extends BlockingQueue<E>, Deque<E> {
/** /**
* Retrieves, but does not remove, the head of the queue represented by * Retrieves, but does not remove, the head of the queue represented by
* this deque (in other words, the first element of this deque). * 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. * exception if this deque is empty.
* *
* <p>This method is equivalent to {@link #getFirst() getFirst}. * <p>This method is equivalent to {@link #getFirst() getFirst}.

View File

@ -39,10 +39,9 @@ import java.util.Collection;
import java.util.Queue; import java.util.Queue;
/** /**
* A {@link java.util.Queue} that additionally supports operations * A {@link Queue} that additionally supports operations that wait for
* that wait for the queue to become non-empty when retrieving an * the queue to become non-empty when retrieving an element, and wait
* element, and wait for space to become available in the queue when * for space to become available in the queue when storing an element.
* storing an element.
* *
* <p>{@code BlockingQueue} methods come in four forms, with different ways * <p>{@code BlockingQueue} methods come in four forms, with different ways
* of handling operations that cannot be satisfied immediately, but may be * of handling operations that cannot be satisfied immediately, but may be
@ -64,22 +63,22 @@ import java.util.Queue;
* </tr> * </tr>
* <tr> * <tr>
* <td><b>Insert</b></td> * <td><b>Insert</b></td>
* <td>{@link #add add(e)}</td> * <td>{@link #add(Object) add(e)}</td>
* <td>{@link #offer offer(e)}</td> * <td>{@link #offer(Object) offer(e)}</td>
* <td>{@link #put put(e)}</td> * <td>{@link #put(Object) put(e)}</td>
* <td>{@link #offer(Object, long, TimeUnit) offer(e, time, unit)}</td> * <td>{@link #offer(Object, long, TimeUnit) offer(e, time, unit)}</td>
* </tr> * </tr>
* <tr> * <tr>
* <td><b>Remove</b></td> * <td><b>Remove</b></td>
* <td>{@link #remove remove()}</td> * <td>{@link #remove() remove()}</td>
* <td>{@link #poll poll()}</td> * <td>{@link #poll() poll()}</td>
* <td>{@link #take take()}</td> * <td>{@link #take() take()}</td>
* <td>{@link #poll(long, TimeUnit) poll(time, unit)}</td> * <td>{@link #poll(long, TimeUnit) poll(time, unit)}</td>
* </tr> * </tr>
* <tr> * <tr>
* <td><b>Examine</b></td> * <td><b>Examine</b></td>
* <td>{@link #element element()}</td> * <td>{@link #element() element()}</td>
* <td>{@link #peek peek()}</td> * <td>{@link #peek() peek()}</td>
* <td><em>not applicable</em></td> * <td><em>not applicable</em></td>
* <td><em>not applicable</em></td> * <td><em>not applicable</em></td>
* </tr> * </tr>
@ -99,7 +98,7 @@ import java.util.Queue;
* *
* <p>{@code BlockingQueue} implementations are designed to be used * <p>{@code BlockingQueue} implementations are designed to be used
* primarily for producer-consumer queues, but additionally support * 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 * possible to remove an arbitrary element from a queue using
* {@code remove(x)}. However, such operations are in general * {@code remove(x)}. However, such operations are in general
* <em>not</em> performed very efficiently, and are intended for only * <em>not</em> performed very efficiently, and are intended for only

View File

@ -159,8 +159,7 @@ import jdk.internal.misc.Unsafe;
* ordering, or on any other objects or values that may transiently * ordering, or on any other objects or values that may transiently
* change while computation is in progress; and except for forEach * change while computation is in progress; and except for forEach
* actions, should ideally be side-effect-free. Bulk operations on * actions, should ideally be side-effect-free. Bulk operations on
* {@link java.util.Map.Entry} objects do not support method {@code * {@link Map.Entry} objects do not support method {@code setValue}.
* setValue}.
* *
* <ul> * <ul>
* <li>forEach: Performs a given action on each element. * <li>forEach: Performs a given action on each element.

View File

@ -42,8 +42,7 @@ import java.util.function.BiFunction;
import java.util.function.Function; import java.util.function.Function;
/** /**
* A {@link java.util.Map} providing thread safety and atomicity * A {@link Map} providing thread safety and atomicity guarantees.
* guarantees.
* *
* <p>To maintain the specified guarantees, default implementations of * <p>To maintain the specified guarantees, default implementations of
* methods including {@link #putIfAbsent} inherited from {@link Map} * methods including {@link #putIfAbsent} inherited from {@link Map}

View File

@ -1821,9 +1821,11 @@ public class ConcurrentSkipListMap<K,V> extends AbstractMap<K,V>
* The set's spliterator additionally reports {@link Spliterator#CONCURRENT}, * The set's spliterator additionally reports {@link Spliterator#CONCURRENT},
* {@link Spliterator#NONNULL}, {@link Spliterator#SORTED} and * {@link Spliterator#NONNULL}, {@link Spliterator#SORTED} and
* {@link Spliterator#ORDERED}, with an encounter order that is ascending * {@link Spliterator#ORDERED}, with an encounter order that is ascending
* key order. The spliterator's comparator (see * key order.
* {@link java.util.Spliterator#getComparator()}) is {@code null} if *
* the map's comparator (see {@link #comparator()}) is {@code null}. * <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 * Otherwise, the spliterator's comparator is the same as or imposes the
* same total ordering as the map's comparator. * same total ordering as the map's comparator.
* *

View File

@ -491,9 +491,9 @@ public class ConcurrentSkipListSet<E>
* encounter order that is ascending order. Overriding implementations * encounter order that is ascending order. Overriding implementations
* should document the reporting of additional characteristic values. * should document the reporting of additional characteristic values.
* *
* <p>The spliterator's comparator (see * <p>The {@linkplain Spliterator#getComparator() spliterator's comparator}
* {@link java.util.Spliterator#getComparator()}) is {@code null} if * is {@code null} if the {@linkplain #comparator() set's comparator}
* the set's comparator (see {@link #comparator()}) is {@code null}. * is {@code null}.
* Otherwise, the spliterator's comparator is the same as or imposes the * Otherwise, the spliterator's comparator is the same as or imposes the
* same total ordering as the set's comparator. * same total ordering as the set's comparator.
* *

View File

@ -46,7 +46,7 @@ import java.util.function.Consumer;
import java.util.function.Predicate; 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: * for all of its operations. Thus, it shares the same basic properties:
* <ul> * <ul>
* <li>It is best suited for applications in which set sizes generally * <li>It is best suited for applications in which set sizes generally

View File

@ -57,8 +57,7 @@ import java.lang.invoke.VarHandle;
* decremented; otherwise, the completion action is performed, and if * decremented; otherwise, the completion action is performed, and if
* this completer itself has a completer, the process is continued * this completer itself has a completer, the process is continued
* with its completer. As is the case with related synchronization * with its completer. As is the case with related synchronization
* components such as {@link java.util.concurrent.Phaser Phaser} and * components such as {@link Phaser} and {@link Semaphore}, these methods
* {@link java.util.concurrent.Semaphore Semaphore}, these methods
* affect only internal counts; they do not establish any further * affect only internal counts; they do not establish any further
* internal bookkeeping. In particular, the identities of pending * internal bookkeeping. In particular, the identities of pending
* tasks are not maintained. As illustrated below, you can create * tasks are not maintained. As illustrated below, you can create

View File

@ -322,17 +322,6 @@ public class DelayQueue<E extends Delayed> extends AbstractQueue<E>
} }
} }
/**
* 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 UnsupportedOperationException {@inheritDoc}
* @throws ClassCastException {@inheritDoc} * @throws ClassCastException {@inheritDoc}
@ -340,22 +329,7 @@ public class DelayQueue<E extends Delayed> extends AbstractQueue<E>
* @throws IllegalArgumentException {@inheritDoc} * @throws IllegalArgumentException {@inheritDoc}
*/ */
public int drainTo(Collection<? super E> c) { public int drainTo(Collection<? super E> c) {
Objects.requireNonNull(c); return drainTo(c, Integer.MAX_VALUE);
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();
}
} }
/** /**
@ -374,8 +348,11 @@ public class DelayQueue<E extends Delayed> extends AbstractQueue<E>
lock.lock(); lock.lock();
try { try {
int n = 0; int n = 0;
for (E e; n < maxElements && (e = peekExpired()) != null;) { for (E first;
c.add(e); // In this order, in case add() throws. n < maxElements
&& (first = q.peek()) != null
&& first.getDelay(NANOSECONDS) <= 0;) {
c.add(first); // In this order, in case add() throws.
q.poll(); q.poll();
++n; ++n;
} }

View File

@ -134,11 +134,11 @@ import java.util.concurrent.locks.ReentrantLock;
* {@link #isCompletedNormally} is true if a task completed without * {@link #isCompletedNormally} is true if a task completed without
* cancellation or encountering an exception; {@link #isCancelled} is * cancellation or encountering an exception; {@link #isCancelled} is
* true if the task was cancelled (in which case {@link #getException} * 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 * {@link #isCompletedAbnormally} is true if a task was either
* cancelled or encountered an exception, in which case {@link * cancelled or encountered an exception, in which case {@link
* #getException} will return either the encountered exception or * #getException} will return either the encountered exception or
* {@link java.util.concurrent.CancellationException}. * {@link CancellationException}.
* *
* <p>The ForkJoinTask class is not usually directly subclassed. * <p>The ForkJoinTask class is not usually directly subclassed.
* Instead, you subclass one of the abstract classes that support a * Instead, you subclass one of the abstract classes that support a
@ -695,13 +695,13 @@ public abstract class ForkJoinTask<V> implements Future<V>, Serializable {
} }
/** /**
* Returns the result of the computation when it {@link #isDone is * Returns the result of the computation when it
* done}. This method differs from {@link #get()} in that * {@linkplain #isDone is done}.
* abnormal completion results in {@code RuntimeException} or * This method differs from {@link #get()} in that abnormal
* {@code Error}, not {@code ExecutionException}, and that * completion results in {@code RuntimeException} or {@code Error},
* interrupts of the calling thread do <em>not</em> cause the * not {@code ExecutionException}, and that interrupts of the
* method to abruptly return by throwing {@code * calling thread do <em>not</em> cause the method to abruptly
* InterruptedException}. * return by throwing {@code InterruptedException}.
* *
* @return the computed result * @return the computed result
*/ */

View File

@ -651,7 +651,7 @@ public class LinkedBlockingDeque<E>
/** /**
* Retrieves and removes the head of the queue represented by this deque. * 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. * exception if this deque is empty.
* *
* <p>This method is equivalent to {@link #removeFirst() removeFirst}. * <p>This method is equivalent to {@link #removeFirst() removeFirst}.
@ -677,7 +677,7 @@ public class LinkedBlockingDeque<E>
/** /**
* Retrieves, but does not remove, the head of the queue represented by * 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. * it throws an exception if this deque is empty.
* *
* <p>This method is equivalent to {@link #getFirst() getFirst}. * <p>This method is equivalent to {@link #getFirst() getFirst}.

View File

@ -1275,8 +1275,7 @@ public class LinkedTransferQueue<E> extends AbstractQueue<E>
* return {@code false}. * return {@code false}.
* *
* @return {@code true} (as specified by * @return {@code true} (as specified by
* {@link java.util.concurrent.BlockingQueue#offer(Object,long,TimeUnit) * {@link BlockingQueue#offer(Object,long,TimeUnit) BlockingQueue.offer})
* BlockingQueue.offer})
* @throws NullPointerException if the specified element is null * @throws NullPointerException if the specified element is null
*/ */
public boolean offer(E e, long timeout, TimeUnit unit) { public boolean offer(E e, long timeout, TimeUnit unit) {
@ -1567,8 +1566,7 @@ public class LinkedTransferQueue<E> extends AbstractQueue<E>
* {@code LinkedTransferQueue} is not capacity constrained. * {@code LinkedTransferQueue} is not capacity constrained.
* *
* @return {@code Integer.MAX_VALUE} (as specified by * @return {@code Integer.MAX_VALUE} (as specified by
* {@link java.util.concurrent.BlockingQueue#remainingCapacity() * {@link BlockingQueue#remainingCapacity()})
* BlockingQueue.remainingCapacity})
*/ */
public int remainingCapacity() { public int remainingCapacity() {
return Integer.MAX_VALUE; return Integer.MAX_VALUE;

View File

@ -42,9 +42,8 @@ import java.util.concurrent.locks.LockSupport;
/** /**
* A reusable synchronization barrier, similar in functionality to * A reusable synchronization barrier, similar in functionality to
* {@link java.util.concurrent.CyclicBarrier CyclicBarrier} and * {@link CyclicBarrier} and {@link CountDownLatch} but supporting
* {@link java.util.concurrent.CountDownLatch CountDownLatch} * more flexible usage.
* but supporting more flexible usage.
* *
* <p><b>Registration.</b> Unlike the case for other barriers, the * <p><b>Registration.</b> Unlike the case for other barriers, the
* number of parties <em>registered</em> to synchronize on a phaser * number of parties <em>registered</em> to synchronize on a phaser

View File

@ -80,7 +80,7 @@ package java.util.concurrent;
* Runnable beeper = () -> System.out.println("beep"); * Runnable beeper = () -> System.out.println("beep");
* ScheduledFuture<?> beeperHandle = * ScheduledFuture<?> beeperHandle =
* scheduler.scheduleAtFixedRate(beeper, 10, 10, SECONDS); * scheduler.scheduleAtFixedRate(beeper, 10, 10, SECONDS);
* Runnable canceller = () -> beeperHandle.cancel(true); * Runnable canceller = () -> beeperHandle.cancel(false);
* scheduler.schedule(canceller, 1, HOURS); * scheduler.schedule(canceller, 1, HOURS);
* } * }
* }}</pre> * }}</pre>
@ -91,8 +91,7 @@ package java.util.concurrent;
public interface ScheduledExecutorService extends ExecutorService { public interface ScheduledExecutorService extends ExecutorService {
/** /**
* Creates and executes a one-shot action that becomes enabled * Submits a one-shot task that becomes enabled after the given delay.
* after the given delay.
* *
* @param command the task to execute * @param command the task to execute
* @param delay the time from now to delay execution * @param delay the time from now to delay execution
@ -102,14 +101,14 @@ public interface ScheduledExecutorService extends ExecutorService {
* {@code null} upon completion * {@code null} upon completion
* @throws RejectedExecutionException if the task cannot be * @throws RejectedExecutionException if the task cannot be
* scheduled for execution * scheduled for execution
* @throws NullPointerException if command is null * @throws NullPointerException if command or unit is null
*/ */
public ScheduledFuture<?> schedule(Runnable command, public ScheduledFuture<?> schedule(Runnable command,
long delay, TimeUnit unit); long delay, TimeUnit unit);
/** /**
* Creates and executes a ScheduledFuture that becomes enabled after the * Submits a value-returning one-shot task that becomes enabled
* given delay. * after the given delay.
* *
* @param callable the function to execute * @param callable the function to execute
* @param delay the time from now to delay execution * @param delay the time from now to delay execution
@ -118,15 +117,15 @@ public interface ScheduledExecutorService extends ExecutorService {
* @return a ScheduledFuture that can be used to extract result or cancel * @return a ScheduledFuture that can be used to extract result or cancel
* @throws RejectedExecutionException if the task cannot be * @throws RejectedExecutionException if the task cannot be
* scheduled for execution * 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, public <V> ScheduledFuture<V> schedule(Callable<V> callable,
long delay, TimeUnit unit); long delay, TimeUnit unit);
/** /**
* Creates and executes a periodic action that becomes enabled first * Submits a periodic action that becomes enabled first after the
* after the given initial delay, and subsequently with the given * given initial delay, and subsequently with the given period;
* period; that is, executions will commence after * that is, executions will commence after
* {@code initialDelay}, then {@code initialDelay + period}, then * {@code initialDelay}, then {@code initialDelay + period}, then
* {@code initialDelay + 2 * period}, and so on. * {@code initialDelay + 2 * period}, and so on.
* *
@ -137,8 +136,8 @@ public interface ScheduledExecutorService extends ExecutorService {
* via the returned future. * via the returned future.
* <li>The executor terminates, also resulting in task cancellation. * <li>The executor terminates, also resulting in task cancellation.
* <li>An execution of the task throws an exception. In this case * <li>An execution of the task throws an exception. In this case
* calling {@link Future#get() get} on the returned future will * calling {@link Future#get() get} on the returned future will throw
* throw {@link ExecutionException}. * {@link ExecutionException}, holding the exception as its cause.
* </ul> * </ul>
* Subsequent executions are suppressed. Subsequent calls to * Subsequent executions are suppressed. Subsequent calls to
* {@link Future#isDone isDone()} on the returned future will * {@link Future#isDone isDone()} on the returned future will
@ -159,7 +158,7 @@ public interface ScheduledExecutorService extends ExecutorService {
* abnormal termination of a task execution. * abnormal termination of a task execution.
* @throws RejectedExecutionException if the task cannot be * @throws RejectedExecutionException if the task cannot be
* scheduled for execution * 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 * @throws IllegalArgumentException if period less than or equal to zero
*/ */
public ScheduledFuture<?> scheduleAtFixedRate(Runnable command, public ScheduledFuture<?> scheduleAtFixedRate(Runnable command,
@ -168,10 +167,10 @@ public interface ScheduledExecutorService extends ExecutorService {
TimeUnit unit); TimeUnit unit);
/** /**
* Creates and executes a periodic action that becomes enabled first * Submits a periodic action that becomes enabled first after the
* after the given initial delay, and subsequently with the * given initial delay, and subsequently with the given delay
* given delay between the termination of one execution and the * between the termination of one execution and the commencement of
* commencement of the next. * the next.
* *
* <p>The sequence of task executions continues indefinitely until * <p>The sequence of task executions continues indefinitely until
* one of the following exceptional completions occur: * one of the following exceptional completions occur:
@ -180,8 +179,8 @@ public interface ScheduledExecutorService extends ExecutorService {
* via the returned future. * via the returned future.
* <li>The executor terminates, also resulting in task cancellation. * <li>The executor terminates, also resulting in task cancellation.
* <li>An execution of the task throws an exception. In this case * <li>An execution of the task throws an exception. In this case
* calling {@link Future#get() get} on the returned future will * calling {@link Future#get() get} on the returned future will throw
* throw {@link ExecutionException}. * {@link ExecutionException}, holding the exception as its cause.
* </ul> * </ul>
* Subsequent executions are suppressed. Subsequent calls to * Subsequent executions are suppressed. Subsequent calls to
* {@link Future#isDone isDone()} on the returned future will * {@link Future#isDone isDone()} on the returned future will
@ -199,7 +198,7 @@ public interface ScheduledExecutorService extends ExecutorService {
* abnormal termination of a task execution. * abnormal termination of a task execution.
* @throws RejectedExecutionException if the task cannot be * @throws RejectedExecutionException if the task cannot be
* scheduled for execution * 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 * @throws IllegalArgumentException if delay less than or equal to zero
*/ */
public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command,

View File

@ -44,6 +44,7 @@ import java.util.Collection;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.locks.ReentrantLock;
@ -87,6 +88,11 @@ import java.util.concurrent.locks.ReentrantLock;
* use {@code allowCoreThreadTimeOut} because this may leave the pool * use {@code allowCoreThreadTimeOut} because this may leave the pool
* without threads to handle tasks once they become eligible to run. * 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 * <p><b>Extension notes:</b> This class overrides the
* {@link ThreadPoolExecutor#execute(Runnable) execute} and * {@link ThreadPoolExecutor#execute(Runnable) execute} and
* {@link AbstractExecutorService#submit(Runnable) submit} * {@link AbstractExecutorService#submit(Runnable) submit}
@ -161,7 +167,7 @@ public class ScheduledThreadPoolExecutor
private volatile boolean continueExistingPeriodicTasksAfterShutdown; 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; private volatile boolean executeExistingDelayedTasksAfterShutdown = true;
@ -292,10 +298,9 @@ public class ScheduledThreadPoolExecutor
* Overrides FutureTask version so as to reset/requeue if periodic. * Overrides FutureTask version so as to reset/requeue if periodic.
*/ */
public void run() { public void run() {
boolean periodic = isPeriodic(); if (!canRunInCurrentRunState(this))
if (!canRunInCurrentRunState(periodic))
cancel(false); cancel(false);
else if (!periodic) else if (!isPeriodic())
super.run(); super.run();
else if (super.runAndReset()) { else if (super.runAndReset()) {
setNextRunTime(); setNextRunTime();
@ -305,15 +310,18 @@ public class ScheduledThreadPoolExecutor
} }
/** /**
* Returns true if can run a task given current run state * Returns true if can run a task given current run state and
* and run-after-shutdown parameters. * run-after-shutdown parameters.
*
* @param periodic true if this task periodic, false if delayed
*/ */
boolean canRunInCurrentRunState(boolean periodic) { boolean canRunInCurrentRunState(RunnableScheduledFuture<?> task) {
return isRunningOrShutdown(periodic ? if (!isShutdown())
continueExistingPeriodicTasksAfterShutdown : return true;
executeExistingDelayedTasksAfterShutdown); if (isStopped())
return false;
return task.isPeriodic()
? continueExistingPeriodicTasksAfterShutdown
: (executeExistingDelayedTasksAfterShutdown
|| task.getDelay(NANOSECONDS) <= 0);
} }
/** /**
@ -332,9 +340,7 @@ public class ScheduledThreadPoolExecutor
reject(task); reject(task);
else { else {
super.getQueue().add(task); super.getQueue().add(task);
if (isShutdown() && if (!canRunInCurrentRunState(task) && remove(task))
!canRunInCurrentRunState(task.isPeriodic()) &&
remove(task))
task.cancel(false); task.cancel(false);
else else
ensurePrestart(); ensurePrestart();
@ -348,13 +354,14 @@ public class ScheduledThreadPoolExecutor
* @param task the task * @param task the task
*/ */
void reExecutePeriodic(RunnableScheduledFuture<?> task) { void reExecutePeriodic(RunnableScheduledFuture<?> task) {
if (canRunInCurrentRunState(true)) { if (canRunInCurrentRunState(task)) {
super.getQueue().add(task); super.getQueue().add(task);
if (!canRunInCurrentRunState(true) && remove(task)) if (canRunInCurrentRunState(task) || !remove(task)) {
task.cancel(false);
else
ensurePrestart(); ensurePrestart();
return;
}
} }
task.cancel(false);
} }
/** /**
@ -367,23 +374,18 @@ public class ScheduledThreadPoolExecutor
getExecuteExistingDelayedTasksAfterShutdownPolicy(); getExecuteExistingDelayedTasksAfterShutdownPolicy();
boolean keepPeriodic = boolean keepPeriodic =
getContinueExistingPeriodicTasksAfterShutdownPolicy(); getContinueExistingPeriodicTasksAfterShutdownPolicy();
if (!keepDelayed && !keepPeriodic) { // Traverse snapshot to avoid iterator exceptions
for (Object e : q.toArray()) // TODO: implement and use efficient removeIf
if (e instanceof RunnableScheduledFuture<?>) // super.getQueue().removeIf(...);
((RunnableScheduledFuture<?>) e).cancel(false); for (Object e : q.toArray()) {
q.clear(); if (e instanceof RunnableScheduledFuture) {
} RunnableScheduledFuture<?> t = (RunnableScheduledFuture<?>)e;
else { if ((t.isPeriodic()
// Traverse snapshot to avoid iterator exceptions ? !keepPeriodic
for (Object e : q.toArray()) { : (!keepDelayed && t.getDelay(NANOSECONDS) > 0))
if (e instanceof RunnableScheduledFuture) { || t.isCancelled()) { // also remove if already cancelled
RunnableScheduledFuture<?> t = if (q.remove(t))
(RunnableScheduledFuture<?>)e; t.cancel(false);
if ((t.isPeriodic() ? !keepPeriodic : !keepDelayed) ||
t.isCancelled()) { // also remove if already cancelled
if (q.remove(t))
t.cancel(false);
}
} }
} }
} }
@ -579,6 +581,34 @@ public class ScheduledThreadPoolExecutor
} }
/** /**
* 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 RejectedExecutionException {@inheritDoc}
* @throws NullPointerException {@inheritDoc} * @throws NullPointerException {@inheritDoc}
* @throws IllegalArgumentException {@inheritDoc} * @throws IllegalArgumentException {@inheritDoc}
@ -604,6 +634,29 @@ public class ScheduledThreadPoolExecutor
} }
/** /**
* 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 RejectedExecutionException {@inheritDoc}
* @throws NullPointerException {@inheritDoc} * @throws NullPointerException {@inheritDoc}
* @throws IllegalArgumentException {@inheritDoc} * @throws IllegalArgumentException {@inheritDoc}
@ -681,9 +734,8 @@ public class ScheduledThreadPoolExecutor
/** /**
* Sets the policy on whether to continue executing existing * Sets the policy on whether to continue executing existing
* periodic tasks even when this executor has been {@code shutdown}. * periodic tasks even when this executor has been {@code shutdown}.
* In this case, these tasks will only terminate upon * In this case, executions will continue until {@code shutdownNow}
* {@code shutdownNow} or after setting the policy to * or the policy is set to {@code false} when already shutdown.
* {@code false} when already shutdown.
* This value is by default {@code false}. * This value is by default {@code false}.
* *
* @param value if {@code true}, continue after shutdown, else don't * @param value if {@code true}, continue after shutdown, else don't
@ -698,9 +750,8 @@ public class ScheduledThreadPoolExecutor
/** /**
* Gets the policy on whether to continue executing existing * Gets the policy on whether to continue executing existing
* periodic tasks even when this executor has been {@code shutdown}. * periodic tasks even when this executor has been {@code shutdown}.
* In this case, these tasks will only terminate upon * In this case, executions will continue until {@code shutdownNow}
* {@code shutdownNow} or after setting the policy to * or the policy is set to {@code false} when already shutdown.
* {@code false} when already shutdown.
* This value is by default {@code false}. * This value is by default {@code false}.
* *
* @return {@code true} if will continue after shutdown * @return {@code true} if will continue after shutdown
@ -904,7 +955,7 @@ public class ScheduledThreadPoolExecutor
/** /**
* Sets f's heapIndex if it is a ScheduledFutureTask. * 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) if (f instanceof ScheduledFutureTask)
((ScheduledFutureTask)f).heapIndex = idx; ((ScheduledFutureTask)f).heapIndex = idx;
} }
@ -1202,41 +1253,12 @@ public class ScheduledThreadPoolExecutor
} }
} }
/**
* 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) { public int drainTo(Collection<? super Runnable> c) {
if (c == null) return drainTo(c, Integer.MAX_VALUE);
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();
}
} }
public int drainTo(Collection<? super Runnable> c, int maxElements) { public int drainTo(Collection<? super Runnable> c, int maxElements) {
if (c == null) Objects.requireNonNull(c);
throw new NullPointerException();
if (c == this) if (c == this)
throw new IllegalArgumentException(); throw new IllegalArgumentException();
if (maxElements <= 0) if (maxElements <= 0)
@ -1244,9 +1266,11 @@ public class ScheduledThreadPoolExecutor
final ReentrantLock lock = this.lock; final ReentrantLock lock = this.lock;
lock.lock(); lock.lock();
try { try {
RunnableScheduledFuture<?> first;
int n = 0; 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. c.add(first); // In this order, in case add() throws.
finishPoll(first); finishPoll(first);
++n; ++n;
@ -1284,7 +1308,13 @@ public class ScheduledThreadPoolExecutor
} }
public Iterator<Runnable> iterator() { 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();
}
} }
/** /**

View File

@ -359,7 +359,7 @@ public class Semaphore implements java.io.Serializable {
* This &quot;barging&quot; behavior can be useful in certain * This &quot;barging&quot; behavior can be useful in certain
* circumstances, even though it breaks fairness. If you want to honor * circumstances, even though it breaks fairness. If you want to honor
* the fairness setting, then use * 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). * which is almost equivalent (it also detects interruption).
* *
* @return {@code true} if a permit was acquired and {@code false} * @return {@code true} if a permit was acquired and {@code false}
@ -523,7 +523,7 @@ public class Semaphore implements java.io.Serializable {
* &quot;barging&quot; behavior can be useful in certain * &quot;barging&quot; behavior can be useful in certain
* circumstances, even though it breaks fairness. If you want to * circumstances, even though it breaks fairness. If you want to
* honor the fairness setting, then use {@link #tryAcquire(int, * 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). * which is almost equivalent (it also detects interruption).
* *
* @param permits the number of permits to acquire * @param permits the number of permits to acquire

View File

@ -1066,7 +1066,7 @@ public class SynchronousQueue<E> extends AbstractQueue<E>
/** /**
* Returns an empty spliterator in which calls to * 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 * @return an empty spliterator
* @since 1.8 * @since 1.8

View File

@ -74,31 +74,28 @@ import java.util.concurrent.locks.ReentrantLock;
* *
* <dt>Core and maximum pool sizes</dt> * <dt>Core and maximum pool sizes</dt>
* *
* <dd style="font-family:'DejaVu Sans', Arial, Helvetica, sans-serif"> * <dd>A {@code ThreadPoolExecutor} will automatically adjust the
* A {@code ThreadPoolExecutor} will automatically adjust the
* pool size (see {@link #getPoolSize}) * pool size (see {@link #getPoolSize})
* according to the bounds set by * according to the bounds set by
* corePoolSize (see {@link #getCorePoolSize}) and * corePoolSize (see {@link #getCorePoolSize}) and
* maximumPoolSize (see {@link #getMaximumPoolSize}). * maximumPoolSize (see {@link #getMaximumPoolSize}).
* *
* When a new task is submitted in method {@link #execute(Runnable)}, * 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 * created to handle the request, even if other worker threads are
* idle. If there are more than corePoolSize but less than * idle. Else if fewer than maximumPoolSize threads are running, a
* maximumPoolSize threads running, a new thread will be created only * new thread will be created to handle the request only if the queue
* if the queue is full. By setting corePoolSize and maximumPoolSize * is full. By setting corePoolSize and maximumPoolSize the same, you
* the same, you create a fixed-size thread pool. By setting * create a fixed-size thread pool. By setting maximumPoolSize to an
* maximumPoolSize to an essentially unbounded value such as {@code * essentially unbounded value such as {@code Integer.MAX_VALUE}, you
* Integer.MAX_VALUE}, you allow the pool to accommodate an arbitrary * allow the pool to accommodate an arbitrary number of concurrent
* number of concurrent tasks. Most typically, core and maximum pool * tasks. Most typically, core and maximum pool sizes are set only
* sizes are set only upon construction, but they may also be changed * upon construction, but they may also be changed dynamically using
* dynamically using {@link #setCorePoolSize} and {@link * {@link #setCorePoolSize} and {@link #setMaximumPoolSize}. </dd>
* #setMaximumPoolSize}. </dd>
* *
* <dt>On-demand construction</dt> * <dt>On-demand construction</dt>
* *
* <dd style="font-family:'DejaVu Sans', Arial, Helvetica, sans-serif"> * <dd>By default, even core threads are initially created and
* By default, even core threads are initially created and
* started only when new tasks arrive, but this can be overridden * started only when new tasks arrive, but this can be overridden
* dynamically using method {@link #prestartCoreThread} or {@link * dynamically using method {@link #prestartCoreThread} or {@link
* #prestartAllCoreThreads}. You probably want to prestart threads if * #prestartAllCoreThreads}. You probably want to prestart threads if
@ -106,8 +103,7 @@ import java.util.concurrent.locks.ReentrantLock;
* *
* <dt>Creating new threads</dt> * <dt>Creating new threads</dt>
* *
* <dd style="font-family:'DejaVu Sans', Arial, Helvetica, sans-serif"> * <dd>New threads are created using a {@link ThreadFactory}. If not
* New threads are created using a {@link ThreadFactory}. If not
* otherwise specified, a {@link Executors#defaultThreadFactory} is * otherwise specified, a {@link Executors#defaultThreadFactory} is
* used, that creates threads to all be in the same {@link * used, that creates threads to all be in the same {@link
* ThreadGroup} and with the same {@code NORM_PRIORITY} priority and * ThreadGroup} and with the same {@code NORM_PRIORITY} priority and
@ -124,8 +120,7 @@ import java.util.concurrent.locks.ReentrantLock;
* *
* <dt>Keep-alive times</dt> * <dt>Keep-alive times</dt>
* *
* <dd style="font-family:'DejaVu Sans', Arial, Helvetica, sans-serif"> * <dd>If the pool currently has more than corePoolSize threads,
* If the pool currently has more than corePoolSize threads,
* excess threads will be terminated if they have been idle for more * excess threads will be terminated if they have been idle for more
* than the keepAliveTime (see {@link #getKeepAliveTime(TimeUnit)}). * than the keepAliveTime (see {@link #getKeepAliveTime(TimeUnit)}).
* This provides a means of reducing resource consumption when the * This provides a means of reducing resource consumption when the
@ -142,8 +137,7 @@ import java.util.concurrent.locks.ReentrantLock;
* *
* <dt>Queuing</dt> * <dt>Queuing</dt>
* *
* <dd style="font-family:'DejaVu Sans', Arial, Helvetica, sans-serif"> * <dd>Any {@link BlockingQueue} may be used to transfer and hold
* Any {@link BlockingQueue} may be used to transfer and hold
* submitted tasks. The use of this queue interacts with pool sizing: * submitted tasks. The use of this queue interacts with pool sizing:
* *
* <ul> * <ul>
@ -208,8 +202,7 @@ import java.util.concurrent.locks.ReentrantLock;
* *
* <dt>Rejected tasks</dt> * <dt>Rejected tasks</dt>
* *
* <dd style="font-family:'DejaVu Sans', Arial, Helvetica, sans-serif"> * <dd>New tasks submitted in method {@link #execute(Runnable)} will be
* New tasks submitted in method {@link #execute(Runnable)} will be
* <em>rejected</em> when the Executor has been shut down, and also when * <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 * the Executor uses finite bounds for both maximum threads and work queue
* capacity, and is saturated. In either case, the {@code execute} method * capacity, and is saturated. In either case, the {@code execute} method
@ -220,9 +213,8 @@ import java.util.concurrent.locks.ReentrantLock;
* *
* <ol> * <ol>
* *
* <li>In the default {@link ThreadPoolExecutor.AbortPolicy}, the * <li>In the default {@link ThreadPoolExecutor.AbortPolicy}, the handler
* handler throws a runtime {@link RejectedExecutionException} upon * throws a runtime {@link RejectedExecutionException} upon rejection.
* rejection.
* *
* <li>In {@link ThreadPoolExecutor.CallerRunsPolicy}, the thread * <li>In {@link ThreadPoolExecutor.CallerRunsPolicy}, the thread
* that invokes {@code execute} itself runs the task. This provides a * that invokes {@code execute} itself runs the task. This provides a
@ -246,8 +238,7 @@ import java.util.concurrent.locks.ReentrantLock;
* *
* <dt>Hook methods</dt> * <dt>Hook methods</dt>
* *
* <dd style="font-family:'DejaVu Sans', Arial, Helvetica, sans-serif"> * <dd>This class provides {@code protected} overridable
* This class provides {@code protected} overridable
* {@link #beforeExecute(Thread, Runnable)} and * {@link #beforeExecute(Thread, Runnable)} and
* {@link #afterExecute(Runnable, Throwable)} methods that are called * {@link #afterExecute(Runnable, Throwable)} methods that are called
* before and after execution of each task. These can be used to * before and after execution of each task. These can be used to
@ -263,8 +254,7 @@ import java.util.concurrent.locks.ReentrantLock;
* *
* <dt>Queue maintenance</dt> * <dt>Queue maintenance</dt>
* *
* <dd style="font-family:'DejaVu Sans', Arial, Helvetica, sans-serif"> * <dd>Method {@link #getQueue()} allows access to the work queue
* Method {@link #getQueue()} allows access to the work queue
* for purposes of monitoring and debugging. Use of this method for * for purposes of monitoring and debugging. Use of this method for
* any other purpose is strongly discouraged. Two supplied methods, * any other purpose is strongly discouraged. Two supplied methods,
* {@link #remove(Runnable)} and {@link #purge} are available to * {@link #remove(Runnable)} and {@link #purge} are available to
@ -273,8 +263,7 @@ import java.util.concurrent.locks.ReentrantLock;
* *
* <dt>Finalization</dt> * <dt>Finalization</dt>
* *
* <dd style="font-family:'DejaVu Sans', Arial, Helvetica, sans-serif"> * <dd>A pool that is no longer referenced in a program <em>AND</em>
* A pool that is no longer referenced in a program <em>AND</em>
* has no remaining threads will be {@code shutdown} automatically. If * has no remaining threads will be {@code shutdown} automatically. If
* you would like to ensure that unreferenced pools are reclaimed even * you would like to ensure that unreferenced pools are reclaimed even
* if users forget to call {@link #shutdown}, then you must arrange * if users forget to call {@link #shutdown}, then you must arrange
@ -850,17 +839,6 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
void onShutdown() { void onShutdown() {
} }
/**
* 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 * Drains the task queue into a new list, normally using
* drainTo. But if the queue is a DelayQueue or any other kind of * drainTo. But if the queue is a DelayQueue or any other kind of
@ -1184,9 +1162,11 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
/** /**
* Creates a new {@code ThreadPoolExecutor} with the given initial * Creates a new {@code ThreadPoolExecutor} with the given initial
* parameters and default thread factory and rejected execution handler. * parameters, the default thread factory and the default rejected
* It may be more convenient to use one of the {@link Executors} factory * execution handler.
* methods instead of this general purpose constructor. *
* <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 * @param corePoolSize the number of threads to keep in the pool, even
* if they are idle, unless {@code allowCoreThreadTimeOut} is set * if they are idle, unless {@code allowCoreThreadTimeOut} is set
@ -1217,7 +1197,8 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
/** /**
* Creates a new {@code ThreadPoolExecutor} with the given initial * 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 * @param corePoolSize the number of threads to keep in the pool, even
* if they are idle, unless {@code allowCoreThreadTimeOut} is set * if they are idle, unless {@code allowCoreThreadTimeOut} is set
@ -1252,7 +1233,8 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
/** /**
* Creates a new {@code ThreadPoolExecutor} with the given initial * 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 * @param corePoolSize the number of threads to keep in the pool, even
* if they are idle, unless {@code allowCoreThreadTimeOut} is set * if they are idle, unless {@code allowCoreThreadTimeOut} is set
@ -1450,6 +1432,11 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
return ! isRunning(ctl.get()); 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 * Returns true if this executor is in the process of terminating
* after {@link #shutdown} or {@link #shutdownNow} but has not * after {@link #shutdown} or {@link #shutdownNow} but has not
@ -2065,7 +2052,10 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
/** /**
* A handler for rejected tasks that throws a * 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 { public static class AbortPolicy implements RejectedExecutionHandler {
/** /**

View File

@ -337,8 +337,8 @@ public enum TimeUnit {
* This is a convenience method that converts timeout arguments * This is a convenience method that converts timeout arguments
* into the form required by the {@code Object.wait} method. * into the form required by the {@code Object.wait} method.
* *
* <p>For example, you could implement a blocking {@code poll} * <p>For example, you could implement a blocking {@code poll} method
* method (see {@link BlockingQueue#poll BlockingQueue.poll}) * (see {@link BlockingQueue#poll(long, TimeUnit) BlockingQueue.poll})
* using: * using:
* *
* <pre> {@code * <pre> {@code

View File

@ -56,11 +56,13 @@ import java.util.function.DoubleBinaryOperator;
* *
* <p>The supplied accumulator function should be side-effect-free, * <p>The supplied accumulator function should be side-effect-free,
* since it may be re-applied when attempted updates fail due to * since it may be re-applied when attempted updates fail due to
* contention among threads. The function is applied with the current * contention among threads. For predictable results, the accumulator
* value as its first argument, and the given update as the second * function should be commutative and associative within the floating
* argument. For example, to maintain a running maximum value, you * point tolerance required in usage contexts. The function is applied
* could supply {@code Double::max} along with {@code * with an existing value (or identity) as one argument, and a given
* Double.NEGATIVE_INFINITY} as the identity. The order of * 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 * accumulation within or across threads is not guaranteed. Thus, this
* class may not be applicable if numerical stability is required, * class may not be applicable if numerical stability is required,
* especially when combining values of substantially different orders * especially when combining values of substantially different orders

View File

@ -59,11 +59,12 @@ import java.util.function.LongBinaryOperator;
* applicable to functions for which the order of accumulation does * applicable to functions for which the order of accumulation does
* not matter. The supplied accumulator function should be * not matter. The supplied accumulator function should be
* side-effect-free, since it may be re-applied when attempted updates * side-effect-free, since it may be re-applied when attempted updates
* fail due to contention among threads. The function is applied with * fail due to contention among threads. For predictable results, the
* the current value as its first argument, and the given update as * accumulator function should be associative and commutative. The
* the second argument. For example, to maintain a running maximum * function is applied with an existing value (or identity) as one
* value, you could supply {@code Long::max} along with {@code * argument, and a given update as the other argument. For example,
* Long.MIN_VALUE} as the identity. * 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 * <p>Class {@link LongAdder} provides analogs of the functionality of
* this class for the common special case of maintaining counts and * this class for the common special case of maintaining counts and

View File

@ -113,8 +113,7 @@ public abstract class AbstractQueuedLongSynchronizer
* @param newState the new state value * @param newState the new state value
*/ */
protected final void setState(long newState) { protected final void setState(long newState) {
// Use putLongVolatile instead of ordinary volatile store when // See JDK-8180620: Clarify VarHandle mixed-access subtleties
// using compareAndSwapLong, for sake of some 32bit systems.
STATE.setVolatile(this, newState); STATE.setVolatile(this, newState);
} }

View File

@ -330,7 +330,7 @@ public class ReentrantLock implements Lock, java.io.Serializable {
* This &quot;barging&quot; behavior can be useful in certain * This &quot;barging&quot; behavior can be useful in certain
* circumstances, even though it breaks fairness. If you want to honor * circumstances, even though it breaks fairness. If you want to honor
* the fairness setting for this lock, then use * 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). * which is almost equivalent (it also detects interruption).
* *
* <p>If the current thread already holds this lock then the hold * <p>If the current thread already holds this lock then the hold

View File

@ -797,7 +797,7 @@ public class ReentrantReadWriteLock
* can be useful in certain circumstances, even though it * can be useful in certain circumstances, even though it
* breaks fairness. If you want to honor the fairness setting * breaks fairness. If you want to honor the fairness setting
* for this lock, then use {@link #tryLock(long, TimeUnit) * 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). * (it also detects interruption).
* *
* <p>If the write lock is held by another thread then * <p>If the write lock is held by another thread then
@ -1029,7 +1029,7 @@ public class ReentrantReadWriteLock
* behavior can be useful in certain circumstances, even * behavior can be useful in certain circumstances, even
* though it breaks fairness. If you want to honor the * though it breaks fairness. If you want to honor the
* fairness setting for this lock, then use {@link * 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). * which is almost equivalent (it also detects interruption).
* *
* <p>If the current thread already holds this lock then the * <p>If the current thread already holds this lock then the

View File

@ -136,4 +136,8 @@ class Adler32 implements Checksum {
@HotSpotIntrinsicCandidate @HotSpotIntrinsicCandidate
private static native int updateByteBuffer(int adler, long addr, private static native int updateByteBuffer(int adler, long addr,
int off, int len); int off, int len);
static {
ZipUtils.loadLibrary();
}
} }

View File

@ -172,4 +172,8 @@ class CRC32 implements Checksum {
throw new NullPointerException(); throw new NullPointerException();
} }
} }
static {
ZipUtils.loadLibrary();
}
} }

View File

@ -154,7 +154,7 @@ class Deflater {
public static final int FULL_FLUSH = 3; public static final int FULL_FLUSH = 3;
static { static {
/* Zip library is loaded from System.initializeSystemClass */ ZipUtils.loadLibrary();
initIDs(); initIDs();
} }

View File

@ -85,7 +85,7 @@ class Inflater {
private static final byte[] defaultBuf = new byte[0]; private static final byte[] defaultBuf = new byte[0];
static { static {
/* Zip library is loaded from System.initializeSystemClass */ ZipUtils.loadLibrary();
initIDs(); initIDs();
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -26,6 +26,8 @@
package java.util.zip; package java.util.zip;
import java.nio.file.attribute.FileTime; import java.nio.file.attribute.FileTime;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.time.Instant; import java.time.Instant;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.ZoneId; import java.time.ZoneId;
@ -245,4 +247,17 @@ class ZipUtils {
// The END header is followed by a variable length comment of size < 64k. // The END header is followed by a variable length comment of size < 64k.
static final long END_MAXLEN = 0xFFFF + ENDHDR; static final long END_MAXLEN = 0xFFFF + ENDHDR;
static final int READBLOCKSZ = 128; static final int READBLOCKSZ = 128;
/**
* Loads zip native library, if not already laoded
*/
static void loadLibrary() {
SecurityManager sm = System.getSecurityManager();
if (sm == null) {
System.loadLibrary("zip");
} else {
PrivilegedAction<Void> pa = () -> { System.loadLibrary("zip"); return null; };
AccessController.doPrivileged(pa);
}
}
} }

View File

@ -31,17 +31,17 @@ import java.net.*;
/** /**
* This class extends <code>ServerSocket</code>s and * This class extends <code>ServerSocket</code> and
* provides secure server sockets using protocols such as the Secure * provides secure server sockets using protocols such as the Secure
* Sockets Layer (SSL) or Transport Layer Security (TLS) protocols. * Sockets Layer (SSL) or Transport Layer Security (TLS) protocols.
* <P> * <P>
* Instances of this class are generally created using a * Instances of this class are generally created using an
* <code>SSLServerSocketFactory</code>. The primary function * <code>SSLServerSocketFactory</code>. The primary function
* of <code>SSLServerSocket</code>s * of an <code>SSLServerSocket</code>
* is to create <code>SSLSocket</code>s by <code>accept</code>ing * is to create <code>SSLSocket</code>s by <code>accept</code>ing
* connections. * connections.
* <P> * <P>
* <code>SSLServerSocket</code>s contain several pieces of state data * An <code>SSLServerSocket</code> contains several pieces of state data
* which are inherited by the <code>SSLSocket</code> at * which are inherited by the <code>SSLSocket</code> at
* socket creation. These include the enabled cipher * socket creation. These include the enabled cipher
* suites and protocols, whether client * suites and protocols, whether client

View File

@ -32,8 +32,8 @@ import java.util.List;
import java.util.function.BiFunction; import java.util.function.BiFunction;
/** /**
* This class extends <code>Socket</code>s and provides secure * This class extends <code>Socket</code> and provides secure
* socket using protocols such as the "Secure * sockets using protocols such as the "Secure
* Sockets Layer" (SSL) or IETF "Transport Layer Security" (TLS) protocols. * Sockets Layer" (SSL) or IETF "Transport Layer Security" (TLS) protocols.
* <P> * <P>
* Such sockets are normal stream sockets, but they * Such sockets are normal stream sockets, but they
@ -105,7 +105,7 @@ import java.util.function.BiFunction;
* non-private (unencrypted) communications will such a ciphersuite be * non-private (unencrypted) communications will such a ciphersuite be
* selected. * selected.
* *
* <P>When <code>SSLSocket</code>s are first created, no handshaking * <P>When an <code>SSLSocket</code> is first created, no handshaking
* is done so that applications may first set their communication * is done so that applications may first set their communication
* preferences: what cipher suites to use, whether the socket should be * preferences: what cipher suites to use, whether the socket should be
* in client or server mode, etc. * in client or server mode, etc.
@ -118,7 +118,7 @@ import java.util.function.BiFunction;
* objects are passed to <em>HandshakeCompletedListener</em> instances, * objects are passed to <em>HandshakeCompletedListener</em> instances,
* which are registered by users of this API. * which are registered by users of this API.
* *
* <code>SSLSocket</code>s are created by <code>SSLSocketFactory</code>s, * An <code>SSLSocket</code> is created by <code>SSLSocketFactory</code>,
* or by <code>accept</code>ing a connection from a * or by <code>accept</code>ing a connection from a
* <code>SSLServerSocket</code>. * <code>SSLServerSocket</code>.
* *

View File

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -40,17 +40,18 @@ public class IOUtils {
* Read up to <code>length</code> of bytes from <code>in</code> * Read up to <code>length</code> of bytes from <code>in</code>
* until EOF is detected. * until EOF is detected.
* @param is input stream, must not be null * @param is input stream, must not be null
* @param length number of bytes to read, -1 or Integer.MAX_VALUE means * @param length number of bytes to read
* read as much as possible
* @param readAll if true, an EOFException will be thrown if not enough * @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 * @return bytes read
* @throws IOException Any IO error or a premature EOF is detected * @throws IOException Any IO error or a premature EOF is detected
*/ */
public static byte[] readFully(InputStream is, int length, boolean readAll) public static byte[] readFully(InputStream is, int length, boolean readAll)
throws IOException { throws IOException {
if (length < 0) {
throw new IOException("Invalid length");
}
byte[] output = {}; byte[] output = {};
if (length == -1) length = Integer.MAX_VALUE;
int pos = 0; int pos = 0;
while (pos < length) { while (pos < length) {
int bytesToRead; int bytesToRead;
@ -64,7 +65,7 @@ public class IOUtils {
} }
int cc = is.read(output, pos, bytesToRead); int cc = is.read(output, pos, bytesToRead);
if (cc < 0) { if (cc < 0) {
if (readAll && length != Integer.MAX_VALUE) { if (readAll) {
throw new EOFException("Detect premature EOF"); throw new EOFException("Detect premature EOF");
} else { } else {
if (output.length != pos) { if (output.length != pos) {

View File

@ -59,9 +59,15 @@ public class SignatureFileVerifier {
/* Are we debugging ? */ /* Are we debugging ? */
private static final Debug debug = Debug.getInstance("jar"); private static final Debug debug = Debug.getInstance("jar");
private static final DisabledAlgorithmConstraints JAR_DISABLED_CHECK = /**
* Holder class to delay initialization of DisabledAlgorithmConstraints
* until needed.
*/
private static class ConfigurationHolder {
static final DisabledAlgorithmConstraints JAR_DISABLED_CHECK =
new DisabledAlgorithmConstraints( new DisabledAlgorithmConstraints(
DisabledAlgorithmConstraints.PROPERTY_JAR_DISABLED_ALGS); DisabledAlgorithmConstraints.PROPERTY_JAR_DISABLED_ALGS);
}
private ArrayList<CodeSigner[]> signerCache; private ArrayList<CodeSigner[]> signerCache;
@ -371,7 +377,7 @@ public class SignatureFileVerifier {
Boolean permitted = permittedAlgs.get(algorithm); Boolean permitted = permittedAlgs.get(algorithm);
if (permitted == null) { if (permitted == null) {
try { try {
JAR_DISABLED_CHECK.permits(algorithm, ConfigurationHolder.JAR_DISABLED_CHECK.permits(algorithm,
new ConstraintsParameters(timestamp)); new ConstraintsParameters(timestamp));
} catch(GeneralSecurityException e) { } catch(GeneralSecurityException e) {
permittedAlgs.put(algorithm, Boolean.FALSE); permittedAlgs.put(algorithm, Boolean.FALSE);

View File

@ -662,6 +662,11 @@ pid_t unix_getParentPidAndTimings(JNIEnv *env, pid_t pid,
return -1; return -1;
} }
// Validate the pid before returning the info in case /proc/pid is racy
if (kill(pid, 0) < 0) {
return -1;
}
*totalTime = psinfo.pr_time.tv_sec * 1000000000L + psinfo.pr_time.tv_nsec; *totalTime = psinfo.pr_time.tv_sec * 1000000000L + psinfo.pr_time.tv_nsec;
*startTime = psinfo.pr_start.tv_sec * (jlong)1000 + *startTime = psinfo.pr_start.tv_sec * (jlong)1000 +

View File

@ -134,16 +134,6 @@
"no_NY", "no_NO@nynorsk", "no_NY", "no_NO@nynorsk",
"sr_SP", "sr_YU", "sr_SP", "sr_YU",
"tchinese", "zh_TW", "tchinese", "zh_TW",
#endif
#ifdef MACOSX
"sr-Latn", "sr_CS", // Mappings as done by old Apple JRS code
"tk", "tk-Cyrl",
"tt-Latn", "tt-Cyrl",
"uz", "uz_UZ",
"uz-Arab", "uz_UZ",
"uz-Latn", "uz_UZ",
"zh-Hans", "zh_CN",
"zh-Hant", "zh_TW",
#endif #endif
"", "", "", "",
}; };

View File

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -137,7 +137,7 @@ import sun.reflect.misc.ReflectUtil;
* <code>MalformedURLException</code> if there is none. An * <code>MalformedURLException</code> if there is none. An
* implementation may choose to find providers by other means. For * implementation may choose to find providers by other means. For
* example, it may support <a * 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> * where the service interface is <code>JMXConnectorProvider</code>.</p>
* *
* <p>Every implementation must support the RMI connector protocol with * <p>Every implementation must support the RMI connector protocol with

View File

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -128,7 +128,7 @@ import javax.management.remote.JMXConnectorFactory.ConnectorFactory;
* <code>MalformedURLException</code> if there is none. An * <code>MalformedURLException</code> if there is none. An
* implementation may choose to find providers by other means. For * implementation may choose to find providers by other means. For
* example, it may support <a * 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> * where the service interface is <code>JMXConnectorServerProvider</code>.</p>
* *
* <p>Every implementation must support the RMI connector protocol with * <p>Every implementation must support the RMI connector protocol with

View File

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * 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 * object registry, and the <em>{@index rmid rmid tool}</em> tool to start
* the activation system daemon. * the activation system daemon.
* *
* <p>
* <dl style="font-family:'DejaVu Sans', Arial, Helvetica, sans serif"> * <dl style="font-family:'DejaVu Sans', Arial, Helvetica, sans serif">
* <dt class="simpleTagLabel">Tool Guides:</dt> * <dt class="simpleTagLabel">Tool Guides:</dt>
* <dd> {@extLink rmiregistry_tool_reference rmiregistry}, * <dd> {@extLink rmiregistry_tool_reference rmiregistry},

View File

@ -23,7 +23,7 @@
/** /**
* @test * @test
* @bug 4238644 4238643 4238641 4944198 * @bug 4238644 4238643 4238641 4944198 8181500
* @summary Test javac regressions in the generation of line number info * @summary Test javac regressions in the generation of line number info
* @author Gordon Hirsch * @author Gordon Hirsch
* *
@ -72,6 +72,7 @@ public class LineNumberInfo extends TestScaffold {
36, 36,
37, 37,
36, 36,
37,
40, 40,
41, 41,
42, 42,
@ -110,6 +111,7 @@ public class LineNumberInfo extends TestScaffold {
85 , 85 ,
93 , 93 ,
96 , 96 ,
105,
107, 107,
111, 111,
119, 119,

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -43,7 +43,8 @@ public class NameTooLong {
for (String[] ps : prefixSuffix) { for (String[] ps : prefixSuffix) {
File f; File f;
try { try {
f = File.createTempFile(ps[0], ps[1]); f = File.createTempFile(ps[0], ps[1],
new File(System.getProperty("test.dir", ".")));
String s = f.toPath().getFileName().toString(); String s = f.toPath().getFileName().toString();
if (!s.startsWith(ps[0].substring(0, 3))) { if (!s.startsWith(ps[0].substring(0, 3))) {
System.err.printf("%s did not start with %s%n", s, System.err.printf("%s did not start with %s%n", s,

View File

@ -30,6 +30,9 @@
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
public class SpecialTempFile { public class SpecialTempFile {
@ -45,21 +48,21 @@ public class SpecialTempFile {
final String exceptionMsg = "Unable to create temporary file"; final String exceptionMsg = "Unable to create temporary file";
String[] dirs = { null, "." }; String[] dirs = { null, "." };
Path testPath = Paths.get(System.getProperty("test.dir", "."));
for (int i = 0; i < prefix.length; i++) { for (int i = 0; i < prefix.length; i++) {
boolean exceptionThrown = false; boolean exceptionThrown = false;
File f = null; File f = null;
for (String dir: dirs) { for (String dir: dirs) {
Path tempDir = Files.createTempDirectory(testPath, dir);
System.out.println("In test " + name + System.out.println("In test " + name +
", creating temp file with prefix, " + ", creating temp file with prefix, " +
prefix[i] + ", suffix, " + suffix[i] + prefix[i] + ", suffix, " + suffix[i] +
", in dir, " + dir); ", in dir, " + tempDir);
try { try {
if (dir == null || dir.isEmpty()) f = File.createTempFile(prefix[i], suffix[i],
f = File.createTempFile(prefix[i], suffix[i]); tempDir.toFile());
else
f = File.createTempFile(prefix[i], suffix[i], new File(dir));
} catch (IOException e) { } catch (IOException e) {
if (exceptionExpected) { if (exceptionExpected) {
if (e.getMessage().startsWith(exceptionMsg)) if (e.getMessage().startsWith(exceptionMsg))
@ -81,10 +84,6 @@ public class SpecialTempFile {
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
// Common test // Common test
final String name = "SpecialTempFile"; final String name = "SpecialTempFile";
File f = new File(System.getProperty("java.io.tmpdir"), name);
if (!f.exists()) {
f.createNewFile();
}
String[] nulPre = { name + "\u0000" }; String[] nulPre = { name + "\u0000" };
String[] nulSuf = { ".test" }; String[] nulSuf = { ".test" };
test("NulName", nulPre, nulSuf, true); test("NulName", nulPre, nulSuf, true);

View File

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -21,10 +21,30 @@
* questions. * questions.
*/ */
/*
* @test
* @bug 4735126
* @summary (cl) ClassLoader.loadClass locks all instances in chain when delegating
* @modules java.base/java.lang:open
* jdk.compiler
* @library /test/lib
* @build jdk.test.lib.compiler.CompilerUtils
* @run main/othervm -Xlog:class+load DelegateTest one-way
* @run main/othervm -Xlog:class+load DelegateTest cross
*/
import java.io.File;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
import java.nio.file.Path;
import java.nio.file.Paths;
public class Starter implements Runnable { import jdk.test.lib.compiler.CompilerUtils;
public class DelegateTest implements Runnable {
private static final Path TEST_DIR = Paths.get(System.getProperty("user.dir", "."));
private static final Path SRC_DIR = Paths.get(System.getProperty("test.src"), "src");
private String id; private String id;
private DelegatingLoader dl; private DelegatingLoader dl;
@ -36,20 +56,21 @@ public class Starter implements Runnable {
System.out.println(line); System.out.println(line);
} }
public static void main(String[] args) { public static void main(String[] args) throws Exception {
URL[] urlsa = new URL[1]; if (!CompilerUtils.compile(SRC_DIR, TEST_DIR)) {
URL[] urlsb = new URL[1]; throw new RuntimeException("Failed to compile "
+ SRC_DIR.toAbsolutePath().toString());
}
URL[] url = new URL[1];
try { try {
String testDir = System.getProperty("test.classes", "."); url[0] = new URL("file://" + TEST_DIR + File.separator);
String sep = System.getProperty("file.separator");
urlsa[0] = new URL("file://" + testDir + sep + "SA" + sep);
urlsb[0] = new URL("file://" + testDir + sep + "SB" + sep);
} catch (MalformedURLException e) { } catch (MalformedURLException e) {
e.printStackTrace(); e.printStackTrace();
} }
// Set up Classloader delegation hierarchy // Set up Classloader delegation hierarchy
saLoader = new DelegatingLoader(urlsa); saLoader = new DelegatingLoader(url);
sbLoader = new DelegatingLoader(urlsb); sbLoader = new DelegatingLoader(url);
String[] saClasses = { "comSA.SupBob", "comSA.Alice" }; String[] saClasses = { "comSA.SupBob", "comSA.Alice" };
String[] sbClasses = { "comSB.SupAlice", "comSB.Bob" }; String[] sbClasses = { "comSB.SupAlice", "comSB.Bob" };
@ -69,11 +90,15 @@ public class Starter implements Runnable {
} }
} }
private static void test(String clsForSA, String clsForSB) { private static void test(String clsForSA, String clsForSB) throws InterruptedException {
Starter ia = new Starter("SA", saLoader, clsForSA); DelegateTest ia = new DelegateTest("SA", saLoader, clsForSA);
Starter ib = new Starter("SB", sbLoader, clsForSB); DelegateTest ib = new DelegateTest("SB", sbLoader, clsForSB);
new Thread(ia).start(); Thread ta = new Thread(ia);
new Thread(ib).start(); Thread tb = new Thread(ib);
ta.start();
tb.start();
ta.join();
tb.join();
} }
public static void sleep() { public static void sleep() {
@ -85,7 +110,7 @@ public class Starter implements Runnable {
} }
} }
private Starter(String id, DelegatingLoader dl, String startClass) { private DelegateTest(String id, DelegatingLoader dl, String startClass) {
this.id = id; this.id = id;
this.dl = dl; this.dl = dl;
this.startClass = startClass; this.startClass = startClass;

View File

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -75,7 +75,7 @@ public class DelegatingLoader extends URLClassLoader {
throws ClassNotFoundException { throws ClassNotFoundException {
for (int i = 0; i < delClasses.length; i++) { for (int i = 0; i < delClasses.length; i++) {
if (delClasses[i].equals(className)) { if (delClasses[i].equals(className)) {
Starter.log("Delegating class loading for " + className); DelegateTest.log("Delegating class loading for " + className);
try { try {
Thread.sleep(500); Thread.sleep(500);
} catch (InterruptedException ie) { } catch (InterruptedException ie) {
@ -85,7 +85,7 @@ public class DelegatingLoader extends URLClassLoader {
} }
} }
Starter.log("Loading local class " + className); DelegateTest.log("Loading local class " + className);
// synchronized (getClassLoadingLock(className)) { // synchronized (getClassLoadingLock(className)) {
return super.loadClass(className, resolve); return super.loadClass(className, resolve);
// } // }

View File

@ -1,122 +0,0 @@
#
# Copyright (c) 2009, 2016, 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 4735126
# @summary (cl) ClassLoader.loadClass locks all instances in chain
# when delegating
#
# @run shell/timeout=300 TestCrossDelegate.sh
# if running by hand on windows, change TESTSRC and TESTCLASSES to "."
if [ "${TESTSRC}" = "" ] ; then
TESTSRC=`pwd`
fi
if [ "${TESTCLASSES}" = "" ] ; then
TESTCLASSES=`pwd`
fi
# if running by hand on windows, change this to appropriate value
if [ "${TESTJAVA}" = "" ] ; then
echo "TESTJAVA not set. Test cannot execute."
echo "FAILED!!!"
exit 1
fi
if [ "${COMPILEJAVA}" = "" ] ; then
COMPILEJAVA="${TESTJAVA}"
fi
# set platform-specific variables
OS=`uname -s`
case "$OS" in
SunOS )
FS="/"
;;
Linux )
FS="/"
;;
Darwin )
FS="/"
;;
AIX )
FS="/"
;;
Windows*)
FS="\\"
;;
CYGWIN* )
FS="\\"
TESTCLASSES=`/usr/bin/cygpath -a -s -m ${TESTCLASSES}`
;;
esac
echo TESTSRC=${TESTSRC}
echo TESTCLASSES=${TESTCLASSES}
echo TESTJAVA=${TESTJAVA}
echo ""
# compile test
${COMPILEJAVA}${FS}bin${FS}javac ${TESTJAVACOPTS} ${TESTTOOLVMOPTS} \
-d ${TESTCLASSES} \
${TESTSRC}${FS}Starter.java ${TESTSRC}${FS}DelegatingLoader.java
STATUS=$?
if [ ${STATUS} -ne 0 ]
then
exit ${STATUS}
fi
# set up test
${COMPILEJAVA}${FS}bin${FS}javac ${TESTJAVACOPTS} ${TESTTOOLVMOPTS} \
-d ${TESTCLASSES}${FS} \
${TESTSRC}${FS}Alice.java ${TESTSRC}${FS}SupBob.java \
${TESTSRC}${FS}Bob.java ${TESTSRC}${FS}SupAlice.java
cd ${TESTCLASSES}
DIRS="SA SB"
for dir in $DIRS
do
if [ -d ${dir} ]; then
rm -rf ${dir}
fi
mkdir ${dir}
mv com${dir} ${dir}
done
# run test
${TESTJAVA}${FS}bin${FS}java \
${TESTVMOPTS} \
--add-opens java.base/java.lang=ALL-UNNAMED \
-verbose:class -Xlog:class+load -cp . \
-Dtest.classes=${TESTCLASSES} \
Starter cross
# -XX:+UnlockDiagnosticVMOptions -XX:+UnsyncloadClass \
# save error status
STATUS=$?
# clean up
rm -rf ${TESTCLASSES}${FS}SA ${TESTCLASSES}${FS}SB
# return
exit ${STATUS}

View File

@ -1,118 +0,0 @@
#
# Copyright (c) 2009, 2016, 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 4735126
# @summary (cl) ClassLoader.loadClass locks all instances in chain
# when delegating
#
# @run shell TestOneWayDelegate.sh
# if running by hand on windows, change TESTSRC and TESTCLASSES to "."
if [ "${TESTSRC}" = "" ] ; then
TESTSRC=`pwd`
fi
if [ "${TESTCLASSES}" = "" ] ; then
TESTCLASSES=`pwd`
fi
# if running by hand on windows, change this to appropriate value
if [ "${TESTJAVA}" = "" ] ; then
echo "TESTJAVA not set. Test cannot execute."
echo "FAILED!!!"
exit 1
fi
if [ "${COMPILEJAVA}" = "" ] ; then
COMPILEJAVA="${TESTJAVA}"
fi
echo TESTSRC=${TESTSRC}
echo TESTCLASSES=${TESTCLASSES}
echo TESTJAVA=${TESTJAVA}
echo COMPILEJAVA=${COMPILEJAVA}
echo ""
# set platform-specific variables
OS=`uname -s`
case "$OS" in
SunOS )
FS="/"
;;
Linux )
FS="/"
;;
Darwin )
FS="/"
;;
AIX )
FS="/"
;;
Windows* | CYGWIN* )
FS="\\"
;;
esac
# compile test
${COMPILEJAVA}${FS}bin${FS}javac ${TESTJAVACOPTS} ${TESTTOOLVMOPTS} \
-d ${TESTCLASSES} \
${TESTSRC}${FS}Starter.java ${TESTSRC}${FS}DelegatingLoader.java
STATUS=$?
if [ ${STATUS} -ne 0 ]
then
exit ${STATUS}
fi
# set up test
${COMPILEJAVA}${FS}bin${FS}javac ${TESTJAVACOPTS} ${TESTTOOLVMOPTS} \
-d ${TESTCLASSES}${FS} \
${TESTSRC}${FS}Alice.java ${TESTSRC}${FS}SupBob.java \
${TESTSRC}${FS}Bob.java ${TESTSRC}${FS}SupAlice.java
cd ${TESTCLASSES}
DIRS="SA SB"
for dir in $DIRS
do
if [ -d ${dir} ]; then
rm -rf ${dir}
fi
mkdir ${dir}
mv com${dir} ${dir}
done
# run test
${TESTJAVA}${FS}bin${FS}java \
${TESTVMOPTS} \
--add-opens java.base/java.lang=ALL-UNNAMED \
-verbose:class -Xlog:class+load -cp . \
-Dtest.classes=${TESTCLASSES} \
Starter one-way
# -XX:+UnlockDiagnosticVMOptions -XX:+UnsyncloadClass \
# save error status
STATUS=$?
# clean up
rm -rf ${TESTCLASSES}${FS}SA ${TESTCLASSES}${FS}SB
# return
exit ${STATUS}

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -31,6 +31,7 @@
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList; import java.util.ArrayList;
public class ParallelProbes { public class ParallelProbes {
@ -47,7 +48,8 @@ public class ParallelProbes {
} }
private Path createTmpFile() throws IOException { private Path createTmpFile() throws IOException {
final Path p = Files.createTempFile("prefix", ".json"); Path dir = Paths.get(System.getProperty("test.dir", "."));
final Path p = Files.createTempFile(dir, "prefix", ".json");
Files.write(p, "{\"test\"}".getBytes()); Files.write(p, "{\"test\"}".getBytes());
System.out.println("Write test file <" + p + ">"); System.out.println("Write test file <" + p + ">");
return p; return p;

View File

@ -32,6 +32,7 @@
*/ */
import java.io.File; import java.io.File;
import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
@ -54,6 +55,11 @@ public class SetDefaultProvider {
new RuntimeException("jar tool not found") new RuntimeException("jar tool not found")
); );
private static Path createTempDirectory(String prefix) throws IOException {
Path testDir = Paths.get(System.getProperty("test.dir", "."));
return Files.createTempDirectory(testDir, prefix);
}
/** /**
* Test override of default FileSystemProvider with the main application * Test override of default FileSystemProvider with the main application
* on the class path. * on the class path.
@ -91,7 +97,7 @@ public class SetDefaultProvider {
* is a module that is patched by an exploded patch. * is a module that is patched by an exploded patch.
*/ */
public void testExplodedModuleWithExplodedPatch() throws Exception { public void testExplodedModuleWithExplodedPatch() throws Exception {
Path patchdir = Files.createTempDirectory("patch"); Path patchdir = createTempDirectory("patch");
String modulePath = System.getProperty("jdk.module.path"); String modulePath = System.getProperty("jdk.module.path");
int exitValue = exec(SET_DEFAULT_FSP, int exitValue = exec(SET_DEFAULT_FSP,
"--patch-module", "m=" + patchdir, "--patch-module", "m=" + patchdir,
@ -105,7 +111,7 @@ public class SetDefaultProvider {
* is a module that is patched by an exploded patch. * is a module that is patched by an exploded patch.
*/ */
public void testExplodedModuleWithJarPatch() throws Exception { public void testExplodedModuleWithJarPatch() throws Exception {
Path patchdir = Files.createTempDirectory("patch"); Path patchdir = createTempDirectory("patch");
Files.createDirectory(patchdir.resolve("m.properties")); Files.createDirectory(patchdir.resolve("m.properties"));
Path patch = createJarFile(patchdir); Path patch = createJarFile(patchdir);
String modulePath = System.getProperty("jdk.module.path"); String modulePath = System.getProperty("jdk.module.path");
@ -142,7 +148,7 @@ public class SetDefaultProvider {
* Creates a JAR file containing the entries in the given file tree. * Creates a JAR file containing the entries in the given file tree.
*/ */
private Path createJarFile(Path dir) throws Exception { private Path createJarFile(Path dir) throws Exception {
Path jar = Files.createTempDirectory("tmp").resolve("m.jar"); Path jar = createTempDirectory("tmp").resolve("m.jar");
String[] args = { "--create", "--file=" + jar, "-C", dir.toString(), "." }; String[] args = { "--create", "--file=" + jar, "-C", dir.toString(), "." };
int ret = JAR_TOOL.run(System.out, System.out, args); int ret = JAR_TOOL.run(System.out, System.out, args);
assertTrue(ret == 0); assertTrue(ret == 0);

View File

@ -56,6 +56,7 @@ import java.util.concurrent.ConcurrentSkipListMap;
import java.util.concurrent.CountDownLatch; import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.LongAdder;
import java.util.regex.Pattern; import java.util.regex.Pattern;
/** /**
@ -391,16 +392,53 @@ public class IteratorMicroBenchmark {
for (Integer o : x.toArray(empty)) for (Integer o : x.toArray(empty))
sum[0] += o; sum[0] += o;
check.sum(sum[0]);}}}, 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") { new Job(klazz + " stream().collect") {
public void work() throws Throwable { public void work() throws Throwable {
for (int i = 0; i < iterations; i++) { for (int i = 0; i < iterations; i++) {
check.sum(x.stream() check.sum(x.stream()
.collect(summingInt(e -> e)));}}}, .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") { new Job(klazz + " parallelStream().collect") {
public void work() throws Throwable { public void work() throws Throwable {
for (int i = 0; i < iterations; i++) { for (int i = 0; i < iterations; i++) {
check.sum(x.parallelStream() 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) { List<Job> dequeJobs(Deque<Integer> x) {

View File

@ -38,6 +38,7 @@ import static java.util.concurrent.TimeUnit.MILLISECONDS;
import java.security.PrivilegedAction; import java.security.PrivilegedAction;
import java.security.PrivilegedExceptionAction; import java.security.PrivilegedExceptionAction;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.concurrent.AbstractExecutorService; import java.util.concurrent.AbstractExecutorService;
@ -192,25 +193,13 @@ public class AbstractExecutorServiceTest extends JSR166TestCase {
} }
/** /**
* execute(null runnable) throws NPE * Submitting null tasks throws NullPointerException
*/ */
public void testExecuteNullRunnable() { public void testNullTaskSubmission() {
ExecutorService e = new DirectExecutorService(); final ExecutorService e = new DirectExecutorService();
try { try (PoolCleaner cleaner = cleaner(e)) {
e.submit((Runnable) null); assertNullTaskSubmissionThrowsNullPointerException(e);
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) {}
} }
/** /**
@ -276,13 +265,15 @@ public class AbstractExecutorServiceTest extends JSR166TestCase {
} }
/** /**
* invokeAny(empty collection) throws IAE * invokeAny(empty collection) throws IllegalArgumentException
*/ */
public void testInvokeAny2() throws Exception { public void testInvokeAny2() throws Exception {
final ExecutorService e = new DirectExecutorService(); final ExecutorService e = new DirectExecutorService();
final Collection<Callable<String>> emptyCollection
= Collections.emptyList();
try (PoolCleaner cleaner = cleaner(e)) { try (PoolCleaner cleaner = cleaner(e)) {
try { try {
e.invokeAny(new ArrayList<Callable<String>>()); e.invokeAny(emptyCollection);
shouldThrow(); shouldThrow();
} catch (IllegalArgumentException success) {} } catch (IllegalArgumentException success) {}
} }
@ -350,12 +341,14 @@ public class AbstractExecutorServiceTest extends JSR166TestCase {
} }
/** /**
* invokeAll(empty collection) returns empty collection * invokeAll(empty collection) returns empty list
*/ */
public void testInvokeAll2() throws InterruptedException { public void testInvokeAll2() throws InterruptedException {
final ExecutorService e = new DirectExecutorService(); final ExecutorService e = new DirectExecutorService();
final Collection<Callable<String>> emptyCollection
= Collections.emptyList();
try (PoolCleaner cleaner = cleaner(e)) { 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()); assertTrue(r.isEmpty());
} }
} }
@ -418,14 +411,14 @@ public class AbstractExecutorServiceTest extends JSR166TestCase {
final ExecutorService e = new DirectExecutorService(); final ExecutorService e = new DirectExecutorService();
try (PoolCleaner cleaner = cleaner(e)) { try (PoolCleaner cleaner = cleaner(e)) {
try { try {
e.invokeAny(null, MEDIUM_DELAY_MS, MILLISECONDS); e.invokeAny(null, randomTimeout(), randomTimeUnit());
shouldThrow(); shouldThrow();
} catch (NullPointerException success) {} } catch (NullPointerException success) {}
} }
} }
/** /**
* timed invokeAny(null time unit) throws NPE * timed invokeAny(null time unit) throws NullPointerException
*/ */
public void testTimedInvokeAnyNullTimeUnit() throws Exception { public void testTimedInvokeAnyNullTimeUnit() throws Exception {
final ExecutorService e = new DirectExecutorService(); final ExecutorService e = new DirectExecutorService();
@ -433,21 +426,22 @@ public class AbstractExecutorServiceTest extends JSR166TestCase {
List<Callable<String>> l = new ArrayList<>(); List<Callable<String>> l = new ArrayList<>();
l.add(new StringTask()); l.add(new StringTask());
try { try {
e.invokeAny(l, MEDIUM_DELAY_MS, null); e.invokeAny(l, randomTimeout(), null);
shouldThrow(); shouldThrow();
} catch (NullPointerException success) {} } catch (NullPointerException success) {}
} }
} }
/** /**
* timed invokeAny(empty collection) throws IAE * timed invokeAny(empty collection) throws IllegalArgumentException
*/ */
public void testTimedInvokeAny2() throws Exception { public void testTimedInvokeAny2() throws Exception {
final ExecutorService e = new DirectExecutorService(); final ExecutorService e = new DirectExecutorService();
final Collection<Callable<String>> emptyCollection
= Collections.emptyList();
try (PoolCleaner cleaner = cleaner(e)) { try (PoolCleaner cleaner = cleaner(e)) {
try { try {
e.invokeAny(new ArrayList<Callable<String>>(), e.invokeAny(emptyCollection, randomTimeout(), randomTimeUnit());
MEDIUM_DELAY_MS, MILLISECONDS);
shouldThrow(); shouldThrow();
} catch (IllegalArgumentException success) {} } catch (IllegalArgumentException success) {}
} }
@ -464,7 +458,7 @@ public class AbstractExecutorServiceTest extends JSR166TestCase {
public Long call() { throw new ArithmeticException(); }}); public Long call() { throw new ArithmeticException(); }});
l.add(null); l.add(null);
try { try {
e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS); e.invokeAny(l, randomTimeout(), randomTimeUnit());
shouldThrow(); shouldThrow();
} catch (NullPointerException success) {} } catch (NullPointerException success) {}
} }
@ -506,13 +500,13 @@ public class AbstractExecutorServiceTest extends JSR166TestCase {
} }
/** /**
* timed invokeAll(null) throws NPE * timed invokeAll(null) throws NullPointerException
*/ */
public void testTimedInvokeAll1() throws InterruptedException { public void testTimedInvokeAll1() throws InterruptedException {
final ExecutorService e = new DirectExecutorService(); final ExecutorService e = new DirectExecutorService();
try (PoolCleaner cleaner = cleaner(e)) { try (PoolCleaner cleaner = cleaner(e)) {
try { try {
e.invokeAll(null, MEDIUM_DELAY_MS, MILLISECONDS); e.invokeAll(null, randomTimeout(), randomTimeUnit());
shouldThrow(); shouldThrow();
} catch (NullPointerException success) {} } catch (NullPointerException success) {}
} }
@ -527,25 +521,28 @@ public class AbstractExecutorServiceTest extends JSR166TestCase {
List<Callable<String>> l = new ArrayList<>(); List<Callable<String>> l = new ArrayList<>();
l.add(new StringTask()); l.add(new StringTask());
try { try {
e.invokeAll(l, MEDIUM_DELAY_MS, null); e.invokeAll(l, randomTimeout(), null);
shouldThrow(); shouldThrow();
} catch (NullPointerException success) {} } catch (NullPointerException success) {}
} }
} }
/** /**
* timed invokeAll(empty collection) returns empty collection * timed invokeAll(empty collection) returns empty list
*/ */
public void testTimedInvokeAll2() throws InterruptedException { public void testTimedInvokeAll2() throws InterruptedException {
final ExecutorService e = new DirectExecutorService(); final ExecutorService e = new DirectExecutorService();
final Collection<Callable<String>> emptyCollection
= Collections.emptyList();
try (PoolCleaner cleaner = cleaner(e)) { 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()); 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 { public void testTimedInvokeAll3() throws InterruptedException {
final ExecutorService e = new DirectExecutorService(); final ExecutorService e = new DirectExecutorService();
@ -554,7 +551,7 @@ public class AbstractExecutorServiceTest extends JSR166TestCase {
l.add(new StringTask()); l.add(new StringTask());
l.add(null); l.add(null);
try { try {
e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS); e.invokeAll(l, randomTimeout(), randomTimeUnit());
shouldThrow(); shouldThrow();
} catch (NullPointerException success) {} } catch (NullPointerException success) {}
} }

View File

@ -80,7 +80,7 @@ public class AbstractQueueTest extends JSR166TestCase {
} }
/** /**
* add throws ISE true if offer fails * add throws IllegalStateException true if offer fails
*/ */
public void testAddF() { public void testAddF() {
Fail q = new Fail(); Fail q = new Fail();
@ -91,7 +91,7 @@ public class AbstractQueueTest extends JSR166TestCase {
} }
/** /**
* add throws NPE if offer does * add throws NullPointerException if offer does
*/ */
public void testAddNPE() { public void testAddNPE() {
Succeed q = new Succeed(); Succeed q = new Succeed();
@ -140,7 +140,7 @@ public class AbstractQueueTest extends JSR166TestCase {
} }
/** /**
* addAll(null) throws NPE * addAll(null) throws NullPointerException
*/ */
public void testAddAll1() { public void testAddAll1() {
Succeed q = new Succeed(); Succeed q = new Succeed();
@ -151,7 +151,7 @@ public class AbstractQueueTest extends JSR166TestCase {
} }
/** /**
* addAll(this) throws IAE * addAll(this) throws IllegalArgumentException
*/ */
public void testAddAllSelf() { public void testAddAllSelf() {
Succeed q = new Succeed(); Succeed q = new Succeed();
@ -162,7 +162,7 @@ public class AbstractQueueTest extends JSR166TestCase {
} }
/** /**
* addAll of a collection with null elements throws NPE * addAll of a collection with null elements throws NullPointerException
*/ */
public void testAddAll2() { public void testAddAll2() {
Succeed q = new Succeed(); Succeed q = new Succeed();
@ -189,7 +189,7 @@ public class AbstractQueueTest extends JSR166TestCase {
} }
/** /**
* addAll throws ISE if an add fails * addAll throws IllegalStateException if an add fails
*/ */
public void testAddAll4() { public void testAddAll4() {
Fail q = new Fail(); Fail q = new Fail();

View File

@ -46,6 +46,7 @@ import junit.framework.AssertionFailedError;
import junit.framework.Test; import junit.framework.Test;
import junit.framework.TestSuite; import junit.framework.TestSuite;
@SuppressWarnings("WaitNotInLoop") // we implement spurious-wakeup freedom
public class AbstractQueuedLongSynchronizerTest extends JSR166TestCase { public class AbstractQueuedLongSynchronizerTest extends JSR166TestCase {
public static void main(String[] args) { public static void main(String[] args) {
main(suite(), args); main(suite(), args);
@ -992,30 +993,30 @@ public class AbstractQueuedLongSynchronizerTest extends JSR166TestCase {
*/ */
public void testAwaitUninterruptibly() { public void testAwaitUninterruptibly() {
final Mutex sync = new Mutex(); final Mutex sync = new Mutex();
final ConditionObject c = sync.newCondition(); final ConditionObject condition = sync.newCondition();
final BooleanLatch pleaseInterrupt = new BooleanLatch(); final BooleanLatch pleaseInterrupt = new BooleanLatch();
Thread t = newStartedThread(new CheckedRunnable() { Thread t = newStartedThread(new CheckedRunnable() {
public void realRun() { public void realRun() {
sync.acquire(); sync.acquire();
assertTrue(pleaseInterrupt.releaseShared(0)); assertTrue(pleaseInterrupt.releaseShared(0));
c.awaitUninterruptibly(); condition.awaitUninterruptibly();
assertTrue(Thread.interrupted()); assertTrue(Thread.interrupted());
assertHasWaitersLocked(sync, c, NO_THREADS); assertHasWaitersLocked(sync, condition, NO_THREADS);
sync.release(); sync.release();
}}); }});
pleaseInterrupt.acquireShared(0); pleaseInterrupt.acquireShared(0);
sync.acquire(); sync.acquire();
assertHasWaitersLocked(sync, c, t); assertHasWaitersLocked(sync, condition, t);
sync.release(); sync.release();
t.interrupt(); t.interrupt();
assertHasWaitersUnlocked(sync, c, t); assertHasWaitersUnlocked(sync, condition, t);
assertThreadStaysAlive(t); assertThreadBlocks(t, Thread.State.WAITING);
sync.acquire(); sync.acquire();
assertHasWaitersLocked(sync, c, t); assertHasWaitersLocked(sync, condition, t);
assertHasExclusiveQueuedThreads(sync, NO_THREADS); assertHasExclusiveQueuedThreads(sync, NO_THREADS);
c.signal(); condition.signal();
assertHasWaitersLocked(sync, c, NO_THREADS); assertHasWaitersLocked(sync, condition, NO_THREADS);
assertHasExclusiveQueuedThreads(sync, t); assertHasExclusiveQueuedThreads(sync, t);
sync.release(); sync.release();
awaitTermination(t); awaitTermination(t);
@ -1158,7 +1159,7 @@ public class AbstractQueuedLongSynchronizerTest extends JSR166TestCase {
waitForQueuedThread(l, t); waitForQueuedThread(l, t);
assertFalse(l.isSignalled()); assertFalse(l.isSignalled());
assertThreadStaysAlive(t); assertThreadBlocks(t, Thread.State.WAITING);
assertHasSharedQueuedThreads(l, t); assertHasSharedQueuedThreads(l, t);
assertTrue(l.releaseShared(0)); assertTrue(l.releaseShared(0));
assertTrue(l.isSignalled()); assertTrue(l.isSignalled());
@ -1183,7 +1184,7 @@ public class AbstractQueuedLongSynchronizerTest extends JSR166TestCase {
waitForQueuedThread(l, t); waitForQueuedThread(l, t);
assertFalse(l.isSignalled()); assertFalse(l.isSignalled());
assertThreadStaysAlive(t); assertThreadBlocks(t, Thread.State.TIMED_WAITING);
assertTrue(l.releaseShared(0)); assertTrue(l.releaseShared(0));
assertTrue(l.isSignalled()); assertTrue(l.isSignalled());
awaitTermination(t); awaitTermination(t);

View File

@ -46,6 +46,7 @@ import junit.framework.AssertionFailedError;
import junit.framework.Test; import junit.framework.Test;
import junit.framework.TestSuite; import junit.framework.TestSuite;
@SuppressWarnings("WaitNotInLoop") // we implement spurious-wakeup freedom
public class AbstractQueuedSynchronizerTest extends JSR166TestCase { public class AbstractQueuedSynchronizerTest extends JSR166TestCase {
public static void main(String[] args) { public static void main(String[] args) {
main(suite(), args); main(suite(), args);
@ -995,30 +996,30 @@ public class AbstractQueuedSynchronizerTest extends JSR166TestCase {
*/ */
public void testAwaitUninterruptibly() { public void testAwaitUninterruptibly() {
final Mutex sync = new Mutex(); final Mutex sync = new Mutex();
final ConditionObject c = sync.newCondition(); final ConditionObject condition = sync.newCondition();
final BooleanLatch pleaseInterrupt = new BooleanLatch(); final BooleanLatch pleaseInterrupt = new BooleanLatch();
Thread t = newStartedThread(new CheckedRunnable() { Thread t = newStartedThread(new CheckedRunnable() {
public void realRun() { public void realRun() {
sync.acquire(); sync.acquire();
assertTrue(pleaseInterrupt.releaseShared(0)); assertTrue(pleaseInterrupt.releaseShared(0));
c.awaitUninterruptibly(); condition.awaitUninterruptibly();
assertTrue(Thread.interrupted()); assertTrue(Thread.interrupted());
assertHasWaitersLocked(sync, c, NO_THREADS); assertHasWaitersLocked(sync, condition, NO_THREADS);
sync.release(); sync.release();
}}); }});
pleaseInterrupt.acquireShared(0); pleaseInterrupt.acquireShared(0);
sync.acquire(); sync.acquire();
assertHasWaitersLocked(sync, c, t); assertHasWaitersLocked(sync, condition, t);
sync.release(); sync.release();
t.interrupt(); t.interrupt();
assertHasWaitersUnlocked(sync, c, t); assertHasWaitersUnlocked(sync, condition, t);
assertThreadStaysAlive(t); assertThreadBlocks(t, Thread.State.WAITING);
sync.acquire(); sync.acquire();
assertHasWaitersLocked(sync, c, t); assertHasWaitersLocked(sync, condition, t);
assertHasExclusiveQueuedThreads(sync, NO_THREADS); assertHasExclusiveQueuedThreads(sync, NO_THREADS);
c.signal(); condition.signal();
assertHasWaitersLocked(sync, c, NO_THREADS); assertHasWaitersLocked(sync, condition, NO_THREADS);
assertHasExclusiveQueuedThreads(sync, t); assertHasExclusiveQueuedThreads(sync, t);
sync.release(); sync.release();
awaitTermination(t); awaitTermination(t);
@ -1161,7 +1162,7 @@ public class AbstractQueuedSynchronizerTest extends JSR166TestCase {
waitForQueuedThread(l, t); waitForQueuedThread(l, t);
assertFalse(l.isSignalled()); assertFalse(l.isSignalled());
assertThreadStaysAlive(t); assertThreadBlocks(t, Thread.State.WAITING);
assertHasSharedQueuedThreads(l, t); assertHasSharedQueuedThreads(l, t);
assertTrue(l.releaseShared(0)); assertTrue(l.releaseShared(0));
assertTrue(l.isSignalled()); assertTrue(l.isSignalled());
@ -1186,7 +1187,7 @@ public class AbstractQueuedSynchronizerTest extends JSR166TestCase {
waitForQueuedThread(l, t); waitForQueuedThread(l, t);
assertFalse(l.isSignalled()); assertFalse(l.isSignalled());
assertThreadStaysAlive(t); assertThreadBlocks(t, Thread.State.TIMED_WAITING);
assertTrue(l.releaseShared(0)); assertTrue(l.releaseShared(0));
assertTrue(l.isSignalled()); assertTrue(l.isSignalled());
awaitTermination(t); awaitTermination(t);

View File

@ -130,7 +130,7 @@ public class ArrayBlockingQueueTest extends JSR166TestCase {
} }
/** /**
* Constructor throws IAE if capacity argument nonpositive * Constructor throws IllegalArgumentException if capacity argument nonpositive
*/ */
public void testConstructor_nonPositiveCapacity() { public void testConstructor_nonPositiveCapacity() {
for (int i : new int[] { 0, -1, Integer.MIN_VALUE }) { for (int i : new int[] { 0, -1, Integer.MIN_VALUE }) {
@ -183,7 +183,7 @@ public class ArrayBlockingQueueTest extends JSR166TestCase {
} }
/** /**
* Initializing from too large collection throws IAE * Initializing from too large collection throws IllegalArgumentException
*/ */
public void testConstructor_collectionTooLarge() { public void testConstructor_collectionTooLarge() {
// just barely fits - succeeds // just barely fits - succeeds
@ -254,7 +254,7 @@ public class ArrayBlockingQueueTest extends JSR166TestCase {
} }
/** /**
* add succeeds if not full; throws ISE if full * add succeeds if not full; throws IllegalStateException if full
*/ */
public void testAdd() { public void testAdd() {
ArrayBlockingQueue q = new ArrayBlockingQueue(SIZE); ArrayBlockingQueue q = new ArrayBlockingQueue(SIZE);
@ -267,7 +267,7 @@ public class ArrayBlockingQueueTest extends JSR166TestCase {
} }
/** /**
* addAll(this) throws IAE * addAll(this) throws IllegalArgumentException
*/ */
public void testAddAllSelf() { public void testAddAllSelf() {
ArrayBlockingQueue q = populatedQueue(SIZE); ArrayBlockingQueue q = populatedQueue(SIZE);
@ -293,7 +293,7 @@ public class ArrayBlockingQueueTest extends JSR166TestCase {
} }
/** /**
* addAll throws ISE if not enough room * addAll throws IllegalStateException if not enough room
*/ */
public void testAddAll_insufficientSpace() { public void testAddAll_insufficientSpace() {
int size = ThreadLocalRandom.current().nextInt(1, SIZE); int size = ThreadLocalRandom.current().nextInt(1, SIZE);
@ -367,7 +367,7 @@ public class ArrayBlockingQueueTest extends JSR166TestCase {
}}); }});
await(pleaseInterrupt); await(pleaseInterrupt);
assertThreadStaysAlive(t); assertThreadBlocks(t, Thread.State.WAITING);
t.interrupt(); t.interrupt();
awaitTermination(t); awaitTermination(t);
assertEquals(SIZE, q.size()); assertEquals(SIZE, q.size());
@ -389,6 +389,13 @@ public class ArrayBlockingQueueTest extends JSR166TestCase {
pleaseTake.countDown(); pleaseTake.countDown();
q.put(86); q.put(86);
Thread.currentThread().interrupt();
try {
q.put(99);
shouldThrow();
} catch (InterruptedException success) {}
assertFalse(Thread.interrupted());
pleaseInterrupt.countDown(); pleaseInterrupt.countDown();
try { try {
q.put(99); q.put(99);
@ -402,7 +409,7 @@ public class ArrayBlockingQueueTest extends JSR166TestCase {
assertEquals(0, q.take()); assertEquals(0, q.take());
await(pleaseInterrupt); await(pleaseInterrupt);
assertThreadStaysAlive(t); assertThreadBlocks(t, Thread.State.WAITING);
t.interrupt(); t.interrupt();
awaitTermination(t); awaitTermination(t);
assertEquals(0, q.remainingCapacity()); assertEquals(0, q.remainingCapacity());
@ -411,7 +418,7 @@ public class ArrayBlockingQueueTest extends JSR166TestCase {
/** /**
* timed offer times out if full and elements not taken * 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 ArrayBlockingQueue q = new ArrayBlockingQueue(2);
final CountDownLatch pleaseInterrupt = new CountDownLatch(1); final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
Thread t = newStartedThread(new CheckedRunnable() { Thread t = newStartedThread(new CheckedRunnable() {
@ -421,15 +428,24 @@ public class ArrayBlockingQueueTest extends JSR166TestCase {
long startTime = System.nanoTime(); long startTime = System.nanoTime();
assertFalse(q.offer(new Object(), timeoutMillis(), MILLISECONDS)); assertFalse(q.offer(new Object(), timeoutMillis(), MILLISECONDS));
assertTrue(millisElapsedSince(startTime) >= timeoutMillis()); 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(); pleaseInterrupt.countDown();
try { try {
q.offer(new Object(), 2 * LONG_DELAY_MS, MILLISECONDS); q.offer(new Object(), 2 * LONG_DELAY_MS, MILLISECONDS);
shouldThrow(); shouldThrow();
} catch (InterruptedException success) {} } catch (InterruptedException success) {}
assertFalse(Thread.interrupted());
}}); }});
await(pleaseInterrupt); await(pleaseInterrupt);
assertThreadStaysAlive(t); assertThreadBlocks(t, Thread.State.TIMED_WAITING);
t.interrupt(); t.interrupt();
awaitTermination(t); awaitTermination(t);
} }
@ -452,9 +468,7 @@ public class ArrayBlockingQueueTest extends JSR166TestCase {
final CountDownLatch pleaseInterrupt = new CountDownLatch(1); final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
Thread t = newStartedThread(new CheckedRunnable() { Thread t = newStartedThread(new CheckedRunnable() {
public void realRun() throws InterruptedException { public void realRun() throws InterruptedException {
for (int i = 0; i < SIZE; ++i) { for (int i = 0; i < SIZE; i++) assertEquals(i, q.take());
assertEquals(i, q.take());
}
Thread.currentThread().interrupt(); Thread.currentThread().interrupt();
try { try {
@ -472,7 +486,7 @@ public class ArrayBlockingQueueTest extends JSR166TestCase {
}}); }});
await(pleaseInterrupt); await(pleaseInterrupt);
assertThreadStaysAlive(t); assertThreadBlocks(t, Thread.State.WAITING);
t.interrupt(); t.interrupt();
awaitTermination(t); awaitTermination(t);
} }
@ -522,24 +536,32 @@ public class ArrayBlockingQueueTest extends JSR166TestCase {
*/ */
public void testInterruptedTimedPoll() throws InterruptedException { public void testInterruptedTimedPoll() throws InterruptedException {
final BlockingQueue<Integer> q = populatedQueue(SIZE); final BlockingQueue<Integer> q = populatedQueue(SIZE);
final CountDownLatch aboutToWait = new CountDownLatch(1); final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
Thread t = newStartedThread(new CheckedRunnable() { Thread t = newStartedThread(new CheckedRunnable() {
public void realRun() throws InterruptedException { public void realRun() throws InterruptedException {
long startTime = System.nanoTime(); 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)); assertEquals(i, (int) q.poll(LONG_DELAY_MS, MILLISECONDS));
}
aboutToWait.countDown(); Thread.currentThread().interrupt();
try { try {
q.poll(LONG_DELAY_MS, MILLISECONDS); q.poll(LONG_DELAY_MS, MILLISECONDS);
shouldThrow(); shouldThrow();
} catch (InterruptedException success) { } catch (InterruptedException success) {}
assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS); 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); await(pleaseInterrupt);
waitForThreadToEnterWaitState(t); assertThreadBlocks(t, Thread.State.TIMED_WAITING);
t.interrupt(); t.interrupt();
awaitTermination(t); awaitTermination(t);
checkEmpty(q); checkEmpty(q);

View File

@ -133,7 +133,7 @@ public abstract class BlockingQueueTest extends JSR166TestCase {
} }
/** /**
* put(null) throws NullPointerException * addAll(null) throws NullPointerException
*/ */
public void testAddAllNull() throws InterruptedException { public void testAddAllNull() throws InterruptedException {
final Collection q = emptyCollection(); final Collection q = emptyCollection();
@ -272,7 +272,7 @@ public abstract class BlockingQueueTest extends JSR166TestCase {
assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS); assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
barrier.await(); barrier.await();
assertThreadStaysAlive(t); assertThreadBlocks(t, Thread.State.TIMED_WAITING);
t.interrupt(); t.interrupt();
awaitTermination(t); awaitTermination(t);
} }
@ -294,7 +294,7 @@ public abstract class BlockingQueueTest extends JSR166TestCase {
}}); }});
await(threadStarted); await(threadStarted);
assertThreadStaysAlive(t); assertThreadBlocks(t, Thread.State.WAITING);
t.interrupt(); t.interrupt();
awaitTermination(t); awaitTermination(t);
} }
@ -335,7 +335,7 @@ public abstract class BlockingQueueTest extends JSR166TestCase {
}}); }});
await(threadStarted); await(threadStarted);
assertThreadStaysAlive(t); assertThreadBlocks(t, Thread.State.TIMED_WAITING);
t.interrupt(); t.interrupt();
awaitTermination(t); awaitTermination(t);
} }

View File

@ -167,12 +167,12 @@ public class Collection8Test extends JSR166TestCase {
} }
if (c instanceof BlockingQueue) { if (c instanceof BlockingQueue) {
BlockingQueue q = (BlockingQueue) c; BlockingQueue q = (BlockingQueue) c;
assertNull(q.poll(0L, MILLISECONDS)); assertNull(q.poll(randomExpiredTimeout(), randomTimeUnit()));
} }
if (c instanceof BlockingDeque) { if (c instanceof BlockingDeque) {
BlockingDeque q = (BlockingDeque) c; BlockingDeque q = (BlockingDeque) c;
assertNull(q.pollFirst(0L, MILLISECONDS)); assertNull(q.pollFirst(randomExpiredTimeout(), randomTimeUnit()));
assertNull(q.pollLast(0L, MILLISECONDS)); assertNull(q.pollLast(randomExpiredTimeout(), randomTimeUnit()));
} }
} }

View File

@ -91,7 +91,7 @@ public class CompletableFutureTest extends JSR166TestCase {
assertNull(f.getNow(null)); assertNull(f.getNow(null));
} catch (Throwable fail) { threadUnexpectedException(fail); } } catch (Throwable fail) { threadUnexpectedException(fail); }
try { try {
f.get(0L, SECONDS); f.get(randomExpiredTimeout(), randomTimeUnit());
shouldThrow(); shouldThrow();
} }
catch (TimeoutException success) {} catch (TimeoutException success) {}
@ -103,11 +103,7 @@ public class CompletableFutureTest extends JSR166TestCase {
try { try {
assertEquals(value, f.join()); assertEquals(value, f.join());
} catch (Throwable fail) { threadUnexpectedException(fail); }
try {
assertEquals(value, f.getNow(null)); assertEquals(value, f.getNow(null));
} catch (Throwable fail) { threadUnexpectedException(fail); }
try {
assertEquals(value, f.get()); assertEquals(value, f.get());
} catch (Throwable fail) { threadUnexpectedException(fail); } } catch (Throwable fail) { threadUnexpectedException(fail); }
assertTrue(f.isDone()); assertTrue(f.isDone());
@ -1269,6 +1265,7 @@ public class CompletableFutureTest extends JSR166TestCase {
r.assertInvoked(); r.assertInvoked();
}} }}
@SuppressWarnings("FutureReturnValueIgnored")
public void testRunAsync_rejectingExecutor() { public void testRunAsync_rejectingExecutor() {
CountingRejectingExecutor e = new CountingRejectingExecutor(); CountingRejectingExecutor e = new CountingRejectingExecutor();
try { try {
@ -1315,6 +1312,7 @@ public class CompletableFutureTest extends JSR166TestCase {
r.assertInvoked(); r.assertInvoked();
}} }}
@SuppressWarnings("FutureReturnValueIgnored")
public void testSupplyAsync_rejectingExecutor() { public void testSupplyAsync_rejectingExecutor() {
CountingRejectingExecutor e = new CountingRejectingExecutor(); CountingRejectingExecutor e = new CountingRejectingExecutor();
try { try {
@ -3265,6 +3263,7 @@ public class CompletableFutureTest extends JSR166TestCase {
/** /**
* Completion methods throw NullPointerException with null arguments * Completion methods throw NullPointerException with null arguments
*/ */
@SuppressWarnings("FutureReturnValueIgnored")
public void testNPE() { public void testNPE() {
CompletableFuture<Integer> f = new CompletableFuture<>(); CompletableFuture<Integer> f = new CompletableFuture<>();
CompletableFuture<Integer> g = new CompletableFuture<>(); CompletableFuture<Integer> g = new CompletableFuture<>();
@ -4326,6 +4325,7 @@ public class CompletableFutureTest extends JSR166TestCase {
} }
/** Test long recursive chains of CompletableFutures with cascading completions */ /** Test long recursive chains of CompletableFutures with cascading completions */
@SuppressWarnings("FutureReturnValueIgnored")
public void testRecursiveChains() throws Throwable { public void testRecursiveChains() throws Throwable {
for (ExecutionMode m : ExecutionMode.values()) for (ExecutionMode m : ExecutionMode.values())
for (boolean addDeadEnds : new boolean[] { true, false }) for (boolean addDeadEnds : new boolean[] { true, false })
@ -4350,6 +4350,7 @@ public class CompletableFutureTest extends JSR166TestCase {
* A single CompletableFuture with many dependents. * A single CompletableFuture with many dependents.
* A demo of scalability - runtime is O(n). * A demo of scalability - runtime is O(n).
*/ */
@SuppressWarnings("FutureReturnValueIgnored")
public void testManyDependents() throws Throwable { public void testManyDependents() throws Throwable {
final int n = expensiveTests ? 1_000_000 : 10; final int n = expensiveTests ? 1_000_000 : 10;
final CompletableFuture<Void> head = new CompletableFuture<>(); final CompletableFuture<Void> head = new CompletableFuture<>();
@ -4379,6 +4380,7 @@ public class CompletableFutureTest extends JSR166TestCase {
} }
/** ant -Dvmoptions=-Xmx8m -Djsr166.expensiveTests=true -Djsr166.tckTestClass=CompletableFutureTest tck */ /** ant -Dvmoptions=-Xmx8m -Djsr166.expensiveTests=true -Djsr166.tckTestClass=CompletableFutureTest tck */
@SuppressWarnings("FutureReturnValueIgnored")
public void testCoCompletionGarbageRetention() throws Throwable { public void testCoCompletionGarbageRetention() throws Throwable {
final int n = expensiveTests ? 1_000_000 : 10; final int n = expensiveTests ? 1_000_000 : 10;
final CompletableFuture<Integer> incomplete = new CompletableFuture<>(); final CompletableFuture<Integer> incomplete = new CompletableFuture<>();

View File

@ -339,7 +339,7 @@ public class ConcurrentLinkedDequeTest extends JSR166TestCase {
} }
/** /**
* addAll(this) throws IAE * addAll(this) throws IllegalArgumentException
*/ */
public void testAddAllSelf() { public void testAddAllSelf() {
ConcurrentLinkedDeque q = populatedDeque(SIZE); ConcurrentLinkedDeque q = populatedDeque(SIZE);

View File

@ -199,7 +199,7 @@ public class ConcurrentLinkedQueueTest extends JSR166TestCase {
} }
/** /**
* addAll(null) throws NPE * addAll(null) throws NullPointerException
*/ */
public void testAddAll1() { public void testAddAll1() {
ConcurrentLinkedQueue q = new ConcurrentLinkedQueue(); ConcurrentLinkedQueue q = new ConcurrentLinkedQueue();
@ -210,7 +210,7 @@ public class ConcurrentLinkedQueueTest extends JSR166TestCase {
} }
/** /**
* addAll(this) throws IAE * addAll(this) throws IllegalArgumentException
*/ */
public void testAddAllSelf() { public void testAddAllSelf() {
ConcurrentLinkedQueue q = populatedQueue(SIZE); ConcurrentLinkedQueue q = populatedQueue(SIZE);
@ -221,7 +221,7 @@ public class ConcurrentLinkedQueueTest extends JSR166TestCase {
} }
/** /**
* addAll of a collection with null elements throws NPE * addAll of a collection with null elements throws NullPointerException
*/ */
public void testAddAll2() { public void testAddAll2() {
ConcurrentLinkedQueue q = new ConcurrentLinkedQueue(); ConcurrentLinkedQueue q = new ConcurrentLinkedQueue();

View File

@ -49,7 +49,7 @@ public class CountDownLatchTest extends JSR166TestCase {
} }
/** /**
* negative constructor argument throws IAE * negative constructor argument throws IllegalArgumentException
*/ */
public void testConstructor() { public void testConstructor() {
try { try {
@ -99,7 +99,7 @@ public class CountDownLatchTest extends JSR166TestCase {
assertEquals(2, l.getCount()); assertEquals(2, l.getCount());
l.countDown(); l.countDown();
assertEquals(1, l.getCount()); assertEquals(1, l.getCount());
assertThreadStaysAlive(t); assertThreadBlocks(t, Thread.State.WAITING);
l.countDown(); l.countDown();
assertEquals(0, l.getCount()); assertEquals(0, l.getCount());
awaitTermination(t); awaitTermination(t);
@ -124,14 +124,14 @@ public class CountDownLatchTest extends JSR166TestCase {
assertEquals(2, l.getCount()); assertEquals(2, l.getCount());
l.countDown(); l.countDown();
assertEquals(1, l.getCount()); assertEquals(1, l.getCount());
assertThreadStaysAlive(t); assertThreadBlocks(t, Thread.State.TIMED_WAITING);
l.countDown(); l.countDown();
assertEquals(0, l.getCount()); assertEquals(0, l.getCount());
awaitTermination(t); awaitTermination(t);
} }
/** /**
* await throws IE if interrupted before counted down * await throws InterruptedException if interrupted before counted down
*/ */
public void testAwait_Interruptible() { public void testAwait_Interruptible() {
final CountDownLatch l = new CountDownLatch(1); final CountDownLatch l = new CountDownLatch(1);
@ -156,13 +156,13 @@ public class CountDownLatchTest extends JSR166TestCase {
}}); }});
await(pleaseInterrupt); await(pleaseInterrupt);
assertThreadStaysAlive(t); assertThreadBlocks(t, Thread.State.WAITING);
t.interrupt(); t.interrupt();
awaitTermination(t); awaitTermination(t);
} }
/** /**
* timed await throws IE if interrupted before counted down * timed await throws InterruptedException if interrupted before counted down
*/ */
public void testTimedAwait_Interruptible() { public void testTimedAwait_Interruptible() {
final CountDownLatch l = new CountDownLatch(1); final CountDownLatch l = new CountDownLatch(1);
@ -187,7 +187,7 @@ public class CountDownLatchTest extends JSR166TestCase {
}}); }});
await(pleaseInterrupt); await(pleaseInterrupt);
assertThreadStaysAlive(t); assertThreadBlocks(t, Thread.State.TIMED_WAITING);
t.interrupt(); t.interrupt();
awaitTermination(t); awaitTermination(t);
} }

View File

@ -32,7 +32,6 @@
*/ */
import static java.util.concurrent.TimeUnit.MILLISECONDS; import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.concurrent.TimeUnit.SECONDS;
import java.util.HashSet; import java.util.HashSet;
import java.util.concurrent.CancellationException; import java.util.concurrent.CancellationException;
@ -104,7 +103,7 @@ public class CountedCompleterTest extends JSR166TestCase {
assertNull(a.getRawResult()); assertNull(a.getRawResult());
try { try {
a.get(0L, SECONDS); a.get(randomExpiredTimeout(), randomTimeUnit());
shouldThrow(); shouldThrow();
} catch (TimeoutException success) { } catch (TimeoutException success) {
} catch (Throwable fail) { threadUnexpectedException(fail); } } catch (Throwable fail) { threadUnexpectedException(fail); }
@ -122,7 +121,7 @@ public class CountedCompleterTest extends JSR166TestCase {
Thread.currentThread().interrupt(); Thread.currentThread().interrupt();
long startTime = System.nanoTime(); long startTime = System.nanoTime();
assertNull(a.join()); assertNull(a.join());
assertTrue(millisElapsedSince(startTime) < SMALL_DELAY_MS); assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
Thread.interrupted(); Thread.interrupted();
} }
@ -130,7 +129,7 @@ public class CountedCompleterTest extends JSR166TestCase {
Thread.currentThread().interrupt(); Thread.currentThread().interrupt();
long startTime = System.nanoTime(); long startTime = System.nanoTime();
a.quietlyJoin(); // should be no-op a.quietlyJoin(); // should be no-op
assertTrue(millisElapsedSince(startTime) < SMALL_DELAY_MS); assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
Thread.interrupted(); Thread.interrupted();
} }
@ -138,9 +137,7 @@ public class CountedCompleterTest extends JSR166TestCase {
assertFalse(a.cancel(true)); assertFalse(a.cancel(true));
try { try {
assertNull(a.get()); assertNull(a.get());
} catch (Throwable fail) { threadUnexpectedException(fail); } assertNull(a.get(randomTimeout(), randomTimeUnit()));
try {
assertNull(a.get(5L, SECONDS));
} catch (Throwable fail) { threadUnexpectedException(fail); } } catch (Throwable fail) { threadUnexpectedException(fail); }
} }
@ -165,7 +162,7 @@ public class CountedCompleterTest extends JSR166TestCase {
{ {
long startTime = System.nanoTime(); long startTime = System.nanoTime();
a.quietlyJoin(); // should be no-op a.quietlyJoin(); // should be no-op
assertTrue(millisElapsedSince(startTime) < SMALL_DELAY_MS); assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
} }
try { try {
@ -175,7 +172,7 @@ public class CountedCompleterTest extends JSR166TestCase {
} catch (Throwable fail) { threadUnexpectedException(fail); } } catch (Throwable fail) { threadUnexpectedException(fail); }
try { try {
a.get(5L, SECONDS); a.get(randomTimeout(), randomTimeUnit());
shouldThrow(); shouldThrow();
} catch (CancellationException success) { } catch (CancellationException success) {
} catch (Throwable fail) { threadUnexpectedException(fail); } } catch (Throwable fail) { threadUnexpectedException(fail); }
@ -203,7 +200,7 @@ public class CountedCompleterTest extends JSR166TestCase {
{ {
long startTime = System.nanoTime(); long startTime = System.nanoTime();
a.quietlyJoin(); // should be no-op a.quietlyJoin(); // should be no-op
assertTrue(millisElapsedSince(startTime) < SMALL_DELAY_MS); assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
} }
try { try {
@ -214,7 +211,7 @@ public class CountedCompleterTest extends JSR166TestCase {
} catch (Throwable fail) { threadUnexpectedException(fail); } } catch (Throwable fail) { threadUnexpectedException(fail); }
try { try {
a.get(5L, SECONDS); a.get(randomTimeout(), randomTimeUnit());
shouldThrow(); shouldThrow();
} catch (ExecutionException success) { } catch (ExecutionException success) {
assertSame(t.getClass(), success.getCause().getClass()); assertSame(t.getClass(), success.getCause().getClass());
@ -729,7 +726,7 @@ public class CountedCompleterTest extends JSR166TestCase {
CCF f = new LCCF(8); CCF f = new LCCF(8);
assertSame(f, f.fork()); assertSame(f, f.fork());
try { try {
f.get(5L, null); f.get(randomTimeout(), null);
shouldThrow(); shouldThrow();
} catch (NullPointerException success) {} } catch (NullPointerException success) {}
}}; }};
@ -1451,7 +1448,7 @@ public class CountedCompleterTest extends JSR166TestCase {
CCF f = new LCCF(8); CCF f = new LCCF(8);
assertSame(f, f.fork()); assertSame(f, f.fork());
try { try {
f.get(5L, null); f.get(randomTimeout(), null);
shouldThrow(); shouldThrow();
} catch (NullPointerException success) {} } catch (NullPointerException success) {}
}}; }};

View File

@ -66,7 +66,7 @@ public class CyclicBarrierTest extends JSR166TestCase {
} }
/** /**
* Creating with negative parties throws IAE * Creating with negative parties throws IllegalArgumentException
*/ */
public void testConstructor1() { public void testConstructor1() {
try { try {
@ -76,7 +76,8 @@ public class CyclicBarrierTest extends JSR166TestCase {
} }
/** /**
* Creating with negative parties and no action throws IAE * Creating with negative parties and no action throws
* IllegalArgumentException
*/ */
public void testConstructor2() { public void testConstructor2() {
try { try {

View File

@ -142,7 +142,7 @@ public class DelayQueueTest extends JSR166TestCase {
* Returns a new queue of given size containing consecutive * Returns a new queue of given size containing consecutive
* PDelays 0 ... n - 1. * PDelays 0 ... n - 1.
*/ */
private DelayQueue<PDelay> populatedQueue(int n) { private static DelayQueue<PDelay> populatedQueue(int n) {
DelayQueue<PDelay> q = new DelayQueue<>(); DelayQueue<PDelay> q = new DelayQueue<>();
assertTrue(q.isEmpty()); assertTrue(q.isEmpty());
for (int i = n - 1; i >= 0; i -= 2) for (int i = n - 1; i >= 0; i -= 2)
@ -261,7 +261,7 @@ public class DelayQueueTest extends JSR166TestCase {
} }
/** /**
* addAll(this) throws IAE * addAll(this) throws IllegalArgumentException
*/ */
public void testAddAllSelf() { public void testAddAllSelf() {
DelayQueue q = populatedQueue(SIZE); DelayQueue q = populatedQueue(SIZE);
@ -365,9 +365,8 @@ public class DelayQueueTest extends JSR166TestCase {
final CountDownLatch pleaseInterrupt = new CountDownLatch(1); final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
Thread t = newStartedThread(new CheckedRunnable() { Thread t = newStartedThread(new CheckedRunnable() {
public void realRun() throws InterruptedException { 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())); assertEquals(new PDelay(i), ((PDelay)q.take()));
}
Thread.currentThread().interrupt(); Thread.currentThread().interrupt();
try { try {
@ -385,7 +384,7 @@ public class DelayQueueTest extends JSR166TestCase {
}}); }});
await(pleaseInterrupt); await(pleaseInterrupt);
assertThreadStaysAlive(t); assertThreadBlocks(t, Thread.State.WAITING);
t.interrupt(); t.interrupt();
awaitTermination(t); awaitTermination(t);
} }
@ -438,10 +437,9 @@ public class DelayQueueTest extends JSR166TestCase {
Thread t = newStartedThread(new CheckedRunnable() { Thread t = newStartedThread(new CheckedRunnable() {
public void realRun() throws InterruptedException { public void realRun() throws InterruptedException {
long startTime = System.nanoTime(); long startTime = System.nanoTime();
for (int i = 0; i < SIZE; ++i) { for (int i = 0; i < SIZE; i++)
assertEquals(new PDelay(i), assertEquals(new PDelay(i),
((PDelay)q.poll(LONG_DELAY_MS, MILLISECONDS))); ((PDelay)q.poll(LONG_DELAY_MS, MILLISECONDS)));
}
Thread.currentThread().interrupt(); Thread.currentThread().interrupt();
try { try {
@ -456,11 +454,12 @@ public class DelayQueueTest extends JSR166TestCase {
shouldThrow(); shouldThrow();
} catch (InterruptedException success) {} } catch (InterruptedException success) {}
assertFalse(Thread.interrupted()); assertFalse(Thread.interrupted());
assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS); assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
}}); }});
await(pleaseInterrupt); await(pleaseInterrupt);
assertThreadStaysAlive(t); assertThreadBlocks(t, Thread.State.TIMED_WAITING);
t.interrupt(); t.interrupt();
awaitTermination(t); awaitTermination(t);
checkEmpty(q); checkEmpty(q);
@ -741,7 +740,9 @@ public class DelayQueueTest extends JSR166TestCase {
public void testTimedPollDelayed() throws InterruptedException { public void testTimedPollDelayed() throws InterruptedException {
DelayQueue q = new DelayQueue(); DelayQueue q = new DelayQueue();
q.add(new NanoDelay(LONG_DELAY_MS * 1000000L)); q.add(new NanoDelay(LONG_DELAY_MS * 1000000L));
long startTime = System.nanoTime();
assertNull(q.poll(timeoutMillis(), MILLISECONDS)); assertNull(q.poll(timeoutMillis(), MILLISECONDS));
assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
} }
/** /**

View File

@ -34,6 +34,7 @@
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Phaser; import java.util.concurrent.Phaser;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.atomic.DoubleAccumulator; import java.util.concurrent.atomic.DoubleAccumulator;
import junit.framework.Test; import junit.framework.Test;
@ -48,135 +49,130 @@ public class DoubleAccumulatorTest extends JSR166TestCase {
} }
/** /**
* default constructed initializes to zero * new instance initialized to supplied identity
*/ */
public void testConstructor() { public void testConstructor() {
DoubleAccumulator ai = new DoubleAccumulator(Double::max, 0.0); for (double identity : new double[] {
assertEquals(0.0, ai.get()); 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 * accumulate accumulates given value to current, and get returns current value
*/ */
public void testAccumulateAndGet() { public void testAccumulateAndGet() {
DoubleAccumulator ai = new DoubleAccumulator(Double::max, 0.0); DoubleAccumulator acc = new DoubleAccumulator(Double::max, 0.0);
ai.accumulate(2.0); acc.accumulate(2.0);
assertEquals(2.0, ai.get()); assertEquals(2.0, acc.get());
ai.accumulate(-4.0); acc.accumulate(-4.0);
assertEquals(2.0, ai.get()); assertEquals(2.0, acc.get());
ai.accumulate(4.0); acc.accumulate(4.0);
assertEquals(4.0, ai.get()); assertEquals(4.0, acc.get());
} }
/** /**
* reset() causes subsequent get() to return zero * reset() causes subsequent get() to return zero
*/ */
public void testReset() { public void testReset() {
DoubleAccumulator ai = new DoubleAccumulator(Double::max, 0.0); DoubleAccumulator acc = new DoubleAccumulator(Double::max, 0.0);
ai.accumulate(2.0); acc.accumulate(2.0);
assertEquals(2.0, ai.get()); assertEquals(2.0, acc.get());
ai.reset(); acc.reset();
assertEquals(0.0, ai.get()); assertEquals(0.0, acc.get());
} }
/** /**
* getThenReset() returns current value; subsequent get() returns zero * getThenReset() returns current value; subsequent get() returns zero
*/ */
public void testGetThenReset() { public void testGetThenReset() {
DoubleAccumulator ai = new DoubleAccumulator(Double::max, 0.0); DoubleAccumulator acc = new DoubleAccumulator(Double::max, 0.0);
ai.accumulate(2.0); acc.accumulate(2.0);
assertEquals(2.0, ai.get()); assertEquals(2.0, acc.get());
assertEquals(2.0, ai.getThenReset()); assertEquals(2.0, acc.getThenReset());
assertEquals(0.0, ai.get()); assertEquals(0.0, acc.get());
} }
/** /**
* toString returns current value. * toString returns current value.
*/ */
public void testToString() { public void testToString() {
DoubleAccumulator ai = new DoubleAccumulator(Double::max, 0.0); DoubleAccumulator acc = new DoubleAccumulator(Double::max, 0.0);
assertEquals("0.0", ai.toString()); assertEquals("0.0", acc.toString());
ai.accumulate(1.0); acc.accumulate(1.0);
assertEquals(Double.toString(1.0), ai.toString()); assertEquals(Double.toString(1.0), acc.toString());
} }
/** /**
* intValue returns current value. * intValue returns current value.
*/ */
public void testIntValue() { public void testIntValue() {
DoubleAccumulator ai = new DoubleAccumulator(Double::max, 0.0); DoubleAccumulator acc = new DoubleAccumulator(Double::max, 0.0);
assertEquals(0, ai.intValue()); assertEquals(0, acc.intValue());
ai.accumulate(1.0); acc.accumulate(1.0);
assertEquals(1, ai.intValue()); assertEquals(1, acc.intValue());
} }
/** /**
* longValue returns current value. * longValue returns current value.
*/ */
public void testLongValue() { public void testLongValue() {
DoubleAccumulator ai = new DoubleAccumulator(Double::max, 0.0); DoubleAccumulator acc = new DoubleAccumulator(Double::max, 0.0);
assertEquals(0, ai.longValue()); assertEquals(0, acc.longValue());
ai.accumulate(1.0); acc.accumulate(1.0);
assertEquals(1, ai.longValue()); assertEquals(1, acc.longValue());
} }
/** /**
* floatValue returns current value. * floatValue returns current value.
*/ */
public void testFloatValue() { public void testFloatValue() {
DoubleAccumulator ai = new DoubleAccumulator(Double::max, 0.0); DoubleAccumulator acc = new DoubleAccumulator(Double::max, 0.0);
assertEquals(0.0f, ai.floatValue()); assertEquals(0.0f, acc.floatValue());
ai.accumulate(1.0); acc.accumulate(1.0);
assertEquals(1.0f, ai.floatValue()); assertEquals(1.0f, acc.floatValue());
} }
/** /**
* doubleValue returns current value. * doubleValue returns current value.
*/ */
public void testDoubleValue() { public void testDoubleValue() {
DoubleAccumulator ai = new DoubleAccumulator(Double::max, 0.0); DoubleAccumulator acc = new DoubleAccumulator(Double::max, 0.0);
assertEquals(0.0, ai.doubleValue()); assertEquals(0.0, acc.doubleValue());
ai.accumulate(1.0); acc.accumulate(1.0);
assertEquals(1.0, ai.doubleValue()); assertEquals(1.0, acc.doubleValue());
} }
/** /**
* accumulates by multiple threads produce correct result * accumulates by multiple threads produce correct result
*/ */
public void testAccumulateAndGetMT() { public void testAccumulateAndGetMT() {
final int incs = 1000000; final DoubleAccumulator acc
final int nthreads = 4; = new DoubleAccumulator((x, y) -> x + y, 0.0);
final ExecutorService pool = Executors.newCachedThreadPool(); final int nThreads = ThreadLocalRandom.current().nextInt(1, 5);
DoubleAccumulator a = new DoubleAccumulator(Double::max, 0.0); final Phaser phaser = new Phaser(nThreads + 1);
Phaser phaser = new Phaser(nthreads + 1); final int incs = 1_000_000;
for (int i = 0; i < nthreads; ++i) final double total = nThreads * incs/2.0 * (incs - 1); // Gauss
pool.execute(new AccTask(a, phaser, incs)); final Runnable task = () -> {
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() {
phaser.arriveAndAwaitAdvance(); phaser.arriveAndAwaitAdvance();
DoubleAccumulator a = acc; for (int i = 0; i < incs; i++) {
for (int i = 0; i < incs; ++i) acc.accumulate((double) i);
a.accumulate(i); assertTrue(acc.get() <= total);
result = a.get(); }
phaser.arrive(); 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());
} }
} }

View File

@ -92,7 +92,7 @@ public class ExchangerTest extends JSR166TestCase {
} }
/** /**
* interrupt during wait for exchange throws IE * interrupt during wait for exchange throws InterruptedException
*/ */
public void testExchange_InterruptedException() { public void testExchange_InterruptedException() {
final Exchanger e = new Exchanger(); final Exchanger e = new Exchanger();
@ -109,7 +109,7 @@ public class ExchangerTest extends JSR166TestCase {
} }
/** /**
* interrupt during wait for timed exchange throws IE * interrupt during wait for timed exchange throws InterruptedException
*/ */
public void testTimedExchange_InterruptedException() { public void testTimedExchange_InterruptedException() {
final Exchanger e = new Exchanger(); final Exchanger e = new Exchanger();

View File

@ -167,7 +167,8 @@ public class ExecutorsTest extends JSR166TestCase {
} }
/** /**
* A new newFixedThreadPool with null ThreadFactory throws NPE * A new newFixedThreadPool with null ThreadFactory throws
* NullPointerException
*/ */
public void testNewFixedThreadPool3() { public void testNewFixedThreadPool3() {
try { try {
@ -177,7 +178,7 @@ public class ExecutorsTest extends JSR166TestCase {
} }
/** /**
* A new newFixedThreadPool with 0 threads throws IAE * A new newFixedThreadPool with 0 threads throws IllegalArgumentException
*/ */
public void testNewFixedThreadPool4() { public void testNewFixedThreadPool4() {
try { try {

View File

@ -32,7 +32,6 @@
*/ */
import static java.util.concurrent.TimeUnit.MILLISECONDS; import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.concurrent.TimeUnit.SECONDS;
import java.util.HashSet; import java.util.HashSet;
import java.util.concurrent.CancellationException; import java.util.concurrent.CancellationException;
@ -111,14 +110,14 @@ public class ForkJoinPool8Test extends JSR166TestCase {
Thread.currentThread().interrupt(); Thread.currentThread().interrupt();
try { try {
a.get(5L, SECONDS); a.get(randomTimeout(), randomTimeUnit());
shouldThrow(); shouldThrow();
} catch (InterruptedException success) { } catch (InterruptedException success) {
} catch (Throwable fail) { threadUnexpectedException(fail); } } catch (Throwable fail) { threadUnexpectedException(fail); }
} }
try { try {
a.get(0L, SECONDS); a.get(randomExpiredTimeout(), randomTimeUnit());
shouldThrow(); shouldThrow();
} catch (TimeoutException success) { } catch (TimeoutException success) {
} catch (Throwable fail) { threadUnexpectedException(fail); } } catch (Throwable fail) { threadUnexpectedException(fail); }
@ -136,9 +135,7 @@ public class ForkJoinPool8Test extends JSR166TestCase {
assertFalse(a.cancel(true)); assertFalse(a.cancel(true));
try { try {
assertNull(a.get()); assertNull(a.get());
} catch (Throwable fail) { threadUnexpectedException(fail); } assertNull(a.get(randomTimeout(), randomTimeUnit()));
try {
assertNull(a.get(5L, SECONDS));
} catch (Throwable fail) { threadUnexpectedException(fail); } } catch (Throwable fail) { threadUnexpectedException(fail); }
} }
@ -163,7 +160,7 @@ public class ForkJoinPool8Test extends JSR166TestCase {
} catch (Throwable fail) { threadUnexpectedException(fail); } } catch (Throwable fail) { threadUnexpectedException(fail); }
try { try {
a.get(5L, SECONDS); a.get(randomTimeout(), randomTimeUnit());
shouldThrow(); shouldThrow();
} catch (CancellationException success) { } catch (CancellationException success) {
} catch (Throwable fail) { threadUnexpectedException(fail); } } catch (Throwable fail) { threadUnexpectedException(fail); }
@ -194,7 +191,7 @@ public class ForkJoinPool8Test extends JSR166TestCase {
} catch (Throwable fail) { threadUnexpectedException(fail); } } catch (Throwable fail) { threadUnexpectedException(fail); }
try { try {
a.get(5L, SECONDS); a.get(randomTimeout(), randomTimeUnit());
shouldThrow(); shouldThrow();
} catch (ExecutionException success) { } catch (ExecutionException success) {
assertSame(t.getClass(), success.getCause().getClass()); assertSame(t.getClass(), success.getCause().getClass());
@ -383,7 +380,7 @@ public class ForkJoinPool8Test extends JSR166TestCase {
protected void realCompute() throws Exception { protected void realCompute() throws Exception {
FibAction f = new FibAction(8); FibAction f = new FibAction(8);
assertSame(f, f.fork()); assertSame(f, f.fork());
assertNull(f.get(5L, SECONDS)); assertNull(f.get(LONG_DELAY_MS, MILLISECONDS));
assertEquals(21, f.result); assertEquals(21, f.result);
checkCompletedNormally(f); checkCompletedNormally(f);
}}; }};
@ -399,7 +396,7 @@ public class ForkJoinPool8Test extends JSR166TestCase {
FibAction f = new FibAction(8); FibAction f = new FibAction(8);
assertSame(f, f.fork()); assertSame(f, f.fork());
try { try {
f.get(5L, null); f.get(randomTimeout(), null);
shouldThrow(); shouldThrow();
} catch (NullPointerException success) {} } catch (NullPointerException success) {}
}}; }};
@ -499,7 +496,7 @@ public class ForkJoinPool8Test extends JSR166TestCase {
FailingFibAction f = new FailingFibAction(8); FailingFibAction f = new FailingFibAction(8);
assertSame(f, f.fork()); assertSame(f, f.fork());
try { try {
f.get(5L, SECONDS); f.get(LONG_DELAY_MS, MILLISECONDS);
shouldThrow(); shouldThrow();
} catch (ExecutionException success) { } catch (ExecutionException success) {
Throwable cause = success.getCause(); Throwable cause = success.getCause();
@ -591,7 +588,7 @@ public class ForkJoinPool8Test extends JSR166TestCase {
assertTrue(f.cancel(true)); assertTrue(f.cancel(true));
assertSame(f, f.fork()); assertSame(f, f.fork());
try { try {
f.get(5L, SECONDS); f.get(LONG_DELAY_MS, MILLISECONDS);
shouldThrow(); shouldThrow();
} catch (CancellationException success) { } catch (CancellationException success) {
checkCancelled(f); checkCancelled(f);
@ -1067,7 +1064,7 @@ public class ForkJoinPool8Test extends JSR166TestCase {
CCF f = new LCCF(null, 8); CCF f = new LCCF(null, 8);
assertSame(f, f.fork()); assertSame(f, f.fork());
try { try {
f.get(5L, null); f.get(randomTimeout(), null);
shouldThrow(); shouldThrow();
} catch (NullPointerException success) {} } catch (NullPointerException success) {}
}}; }};

View File

@ -38,6 +38,7 @@ import java.security.PrivilegedAction;
import java.security.PrivilegedExceptionAction; import java.security.PrivilegedExceptionAction;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch; import java.util.concurrent.CountDownLatch;
@ -267,8 +268,8 @@ public class ForkJoinPoolTest extends JSR166TestCase {
assertFalse(p.awaitTermination(Long.MIN_VALUE, MILLISECONDS)); assertFalse(p.awaitTermination(Long.MIN_VALUE, MILLISECONDS));
assertFalse(p.awaitTermination(-1L, NANOSECONDS)); assertFalse(p.awaitTermination(-1L, NANOSECONDS));
assertFalse(p.awaitTermination(-1L, MILLISECONDS)); assertFalse(p.awaitTermination(-1L, MILLISECONDS));
assertFalse(p.awaitTermination(0L, NANOSECONDS)); assertFalse(p.awaitTermination(randomExpiredTimeout(),
assertFalse(p.awaitTermination(0L, MILLISECONDS)); randomTimeUnit()));
long timeoutNanos = 999999L; long timeoutNanos = 999999L;
long startTime = System.nanoTime(); long startTime = System.nanoTime();
assertFalse(p.awaitTermination(timeoutNanos, NANOSECONDS)); assertFalse(p.awaitTermination(timeoutNanos, NANOSECONDS));
@ -449,7 +450,7 @@ public class ForkJoinPoolTest extends JSR166TestCase {
done.set(true); done.set(true);
}}); }});
assertNull(future.get()); assertNull(future.get());
assertNull(future.get(0, MILLISECONDS)); assertNull(future.get(randomExpiredTimeout(), randomTimeUnit()));
assertTrue(done.get()); assertTrue(done.get());
assertTrue(future.isDone()); assertTrue(future.isDone());
assertFalse(future.isCancelled()); assertFalse(future.isCancelled());
@ -730,13 +731,14 @@ public class ForkJoinPoolTest extends JSR166TestCase {
} }
/** /**
* invokeAll(empty collection) returns empty collection * invokeAll(empty collection) returns empty list
*/ */
public void testInvokeAll2() throws InterruptedException { public void testInvokeAll2() throws InterruptedException {
ExecutorService e = new ForkJoinPool(1); ExecutorService e = new ForkJoinPool(1);
final Collection<Callable<String>> emptyCollection
= Collections.emptyList();
try (PoolCleaner cleaner = cleaner(e)) { try (PoolCleaner cleaner = cleaner(e)) {
List<Future<String>> r List<Future<String>> r = e.invokeAll(emptyCollection);
= e.invokeAll(new ArrayList<Callable<String>>());
assertTrue(r.isEmpty()); assertTrue(r.isEmpty());
} }
} }
@ -800,7 +802,7 @@ public class ForkJoinPoolTest extends JSR166TestCase {
ExecutorService e = new ForkJoinPool(1); ExecutorService e = new ForkJoinPool(1);
try (PoolCleaner cleaner = cleaner(e)) { try (PoolCleaner cleaner = cleaner(e)) {
try { try {
e.invokeAny(null, MEDIUM_DELAY_MS, MILLISECONDS); e.invokeAny(null, randomTimeout(), randomTimeUnit());
shouldThrow(); shouldThrow();
} catch (NullPointerException success) {} } catch (NullPointerException success) {}
} }
@ -815,7 +817,7 @@ public class ForkJoinPoolTest extends JSR166TestCase {
List<Callable<String>> l = new ArrayList<>(); List<Callable<String>> l = new ArrayList<>();
l.add(new StringTask()); l.add(new StringTask());
try { try {
e.invokeAny(l, MEDIUM_DELAY_MS, null); e.invokeAny(l, randomTimeout(), null);
shouldThrow(); shouldThrow();
} catch (NullPointerException success) {} } catch (NullPointerException success) {}
} }
@ -829,7 +831,7 @@ public class ForkJoinPoolTest extends JSR166TestCase {
try (PoolCleaner cleaner = cleaner(e)) { try (PoolCleaner cleaner = cleaner(e)) {
try { try {
e.invokeAny(new ArrayList<Callable<String>>(), e.invokeAny(new ArrayList<Callable<String>>(),
MEDIUM_DELAY_MS, MILLISECONDS); randomTimeout(), randomTimeUnit());
shouldThrow(); shouldThrow();
} catch (IllegalArgumentException success) {} } catch (IllegalArgumentException success) {}
} }
@ -846,7 +848,7 @@ public class ForkJoinPoolTest extends JSR166TestCase {
l.add(latchAwaitingStringTask(latch)); l.add(latchAwaitingStringTask(latch));
l.add(null); l.add(null);
try { try {
e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS); e.invokeAny(l, randomTimeout(), randomTimeUnit());
shouldThrow(); shouldThrow();
} catch (NullPointerException success) {} } catch (NullPointerException success) {}
latch.countDown(); latch.countDown();
@ -895,7 +897,7 @@ public class ForkJoinPoolTest extends JSR166TestCase {
ExecutorService e = new ForkJoinPool(1); ExecutorService e = new ForkJoinPool(1);
try (PoolCleaner cleaner = cleaner(e)) { try (PoolCleaner cleaner = cleaner(e)) {
try { try {
e.invokeAll(null, MEDIUM_DELAY_MS, MILLISECONDS); e.invokeAll(null, randomTimeout(), randomTimeUnit());
shouldThrow(); shouldThrow();
} catch (NullPointerException success) {} } catch (NullPointerException success) {}
} }
@ -910,21 +912,23 @@ public class ForkJoinPoolTest extends JSR166TestCase {
List<Callable<String>> l = new ArrayList<>(); List<Callable<String>> l = new ArrayList<>();
l.add(new StringTask()); l.add(new StringTask());
try { try {
e.invokeAll(l, MEDIUM_DELAY_MS, null); e.invokeAll(l, randomTimeout(), null);
shouldThrow(); shouldThrow();
} catch (NullPointerException success) {} } catch (NullPointerException success) {}
} }
} }
/** /**
* timed invokeAll(empty collection) returns empty collection * timed invokeAll(empty collection) returns empty list
*/ */
public void testTimedInvokeAll2() throws InterruptedException { public void testTimedInvokeAll2() throws InterruptedException {
ExecutorService e = new ForkJoinPool(1); ExecutorService e = new ForkJoinPool(1);
final Collection<Callable<String>> emptyCollection
= Collections.emptyList();
try (PoolCleaner cleaner = cleaner(e)) { try (PoolCleaner cleaner = cleaner(e)) {
List<Future<String>> r List<Future<String>> r
= e.invokeAll(new ArrayList<Callable<String>>(), = e.invokeAll(emptyCollection,
MEDIUM_DELAY_MS, MILLISECONDS); randomTimeout(), randomTimeUnit());
assertTrue(r.isEmpty()); assertTrue(r.isEmpty());
} }
} }
@ -939,7 +943,7 @@ public class ForkJoinPoolTest extends JSR166TestCase {
l.add(new StringTask()); l.add(new StringTask());
l.add(null); l.add(null);
try { try {
e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS); e.invokeAll(l, randomTimeout(), randomTimeUnit());
shouldThrow(); shouldThrow();
} catch (NullPointerException success) {} } catch (NullPointerException success) {}
} }

View File

@ -32,7 +32,6 @@
*/ */
import static java.util.concurrent.TimeUnit.MILLISECONDS; import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.concurrent.TimeUnit.SECONDS;
import java.util.Arrays; import java.util.Arrays;
import java.util.concurrent.CountDownLatch; import java.util.concurrent.CountDownLatch;
@ -131,7 +130,7 @@ public class ForkJoinTask8Test extends JSR166TestCase {
((BinaryAsyncAction)a).getForkJoinTaskTag()); ((BinaryAsyncAction)a).getForkJoinTaskTag());
try { try {
a.get(0L, SECONDS); a.get(randomExpiredTimeout(), randomTimeUnit());
shouldThrow(); shouldThrow();
} catch (TimeoutException success) { } catch (TimeoutException success) {
} catch (Throwable fail) { threadUnexpectedException(fail); } } catch (Throwable fail) { threadUnexpectedException(fail); }
@ -156,7 +155,7 @@ public class ForkJoinTask8Test extends JSR166TestCase {
Thread.currentThread().interrupt(); Thread.currentThread().interrupt();
long startTime = System.nanoTime(); long startTime = System.nanoTime();
assertSame(expected, a.join()); assertSame(expected, a.join());
assertTrue(millisElapsedSince(startTime) < SMALL_DELAY_MS); assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
Thread.interrupted(); Thread.interrupted();
} }
@ -164,7 +163,7 @@ public class ForkJoinTask8Test extends JSR166TestCase {
Thread.currentThread().interrupt(); Thread.currentThread().interrupt();
long startTime = System.nanoTime(); long startTime = System.nanoTime();
a.quietlyJoin(); // should be no-op a.quietlyJoin(); // should be no-op
assertTrue(millisElapsedSince(startTime) < SMALL_DELAY_MS); assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
Thread.interrupted(); Thread.interrupted();
} }
@ -172,9 +171,7 @@ public class ForkJoinTask8Test extends JSR166TestCase {
assertFalse(a.cancel(true)); assertFalse(a.cancel(true));
try { try {
assertSame(expected, a.get()); assertSame(expected, a.get());
} catch (Throwable fail) { threadUnexpectedException(fail); } assertSame(expected, a.get(randomTimeout(), randomTimeUnit()));
try {
assertSame(expected, a.get(5L, SECONDS));
} catch (Throwable fail) { threadUnexpectedException(fail); } } catch (Throwable fail) { threadUnexpectedException(fail); }
} }
@ -202,7 +199,7 @@ public class ForkJoinTask8Test extends JSR166TestCase {
{ {
long startTime = System.nanoTime(); long startTime = System.nanoTime();
a.quietlyJoin(); // should be no-op a.quietlyJoin(); // should be no-op
assertTrue(millisElapsedSince(startTime) < SMALL_DELAY_MS); assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
} }
try { try {
@ -213,7 +210,7 @@ public class ForkJoinTask8Test extends JSR166TestCase {
} catch (Throwable fail) { threadUnexpectedException(fail); } } catch (Throwable fail) { threadUnexpectedException(fail); }
try { try {
a.get(5L, SECONDS); a.get(randomTimeout(), randomTimeUnit());
shouldThrow(); shouldThrow();
} catch (ExecutionException success) { } catch (ExecutionException success) {
assertSame(t.getClass(), success.getCause().getClass()); assertSame(t.getClass(), success.getCause().getClass());
@ -515,7 +512,7 @@ public class ForkJoinTask8Test extends JSR166TestCase {
AsyncFib f = new AsyncFib(8); AsyncFib f = new AsyncFib(8);
assertSame(f, f.fork()); assertSame(f, f.fork());
try { try {
f.get(5L, null); f.get(randomTimeout(), null);
shouldThrow(); shouldThrow();
} catch (NullPointerException success) {} } catch (NullPointerException success) {}
}}; }};

View File

@ -32,7 +32,6 @@
*/ */
import static java.util.concurrent.TimeUnit.MILLISECONDS; import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.concurrent.TimeUnit.SECONDS;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashSet; import java.util.HashSet;
@ -104,7 +103,7 @@ public class ForkJoinTaskTest extends JSR166TestCase {
assertNull(a.getRawResult()); assertNull(a.getRawResult());
try { try {
a.get(0L, SECONDS); a.get(randomExpiredTimeout(), randomTimeUnit());
shouldThrow(); shouldThrow();
} catch (TimeoutException success) { } catch (TimeoutException success) {
} catch (Throwable fail) { threadUnexpectedException(fail); } } catch (Throwable fail) { threadUnexpectedException(fail); }
@ -126,7 +125,7 @@ public class ForkJoinTaskTest extends JSR166TestCase {
Thread.currentThread().interrupt(); Thread.currentThread().interrupt();
long startTime = System.nanoTime(); long startTime = System.nanoTime();
assertSame(expected, a.join()); assertSame(expected, a.join());
assertTrue(millisElapsedSince(startTime) < SMALL_DELAY_MS); assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
Thread.interrupted(); Thread.interrupted();
} }
@ -134,7 +133,7 @@ public class ForkJoinTaskTest extends JSR166TestCase {
Thread.currentThread().interrupt(); Thread.currentThread().interrupt();
long startTime = System.nanoTime(); long startTime = System.nanoTime();
a.quietlyJoin(); // should be no-op a.quietlyJoin(); // should be no-op
assertTrue(millisElapsedSince(startTime) < SMALL_DELAY_MS); assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
Thread.interrupted(); Thread.interrupted();
} }
@ -142,9 +141,7 @@ public class ForkJoinTaskTest extends JSR166TestCase {
assertFalse(a.cancel(true)); assertFalse(a.cancel(true));
try { try {
assertSame(expected, a.get()); assertSame(expected, a.get());
} catch (Throwable fail) { threadUnexpectedException(fail); } assertSame(expected, a.get(randomTimeout(), randomTimeUnit()));
try {
assertSame(expected, a.get(5L, SECONDS));
} catch (Throwable fail) { threadUnexpectedException(fail); } } catch (Throwable fail) { threadUnexpectedException(fail); }
} }
@ -169,7 +166,7 @@ public class ForkJoinTaskTest extends JSR166TestCase {
{ {
long startTime = System.nanoTime(); long startTime = System.nanoTime();
a.quietlyJoin(); // should be no-op a.quietlyJoin(); // should be no-op
assertTrue(millisElapsedSince(startTime) < SMALL_DELAY_MS); assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
} }
try { try {
@ -179,7 +176,7 @@ public class ForkJoinTaskTest extends JSR166TestCase {
} catch (Throwable fail) { threadUnexpectedException(fail); } } catch (Throwable fail) { threadUnexpectedException(fail); }
try { try {
a.get(5L, SECONDS); a.get(randomTimeout(), randomTimeUnit());
shouldThrow(); shouldThrow();
} catch (CancellationException success) { } catch (CancellationException success) {
} catch (Throwable fail) { threadUnexpectedException(fail); } } catch (Throwable fail) { threadUnexpectedException(fail); }
@ -207,7 +204,7 @@ public class ForkJoinTaskTest extends JSR166TestCase {
{ {
long startTime = System.nanoTime(); long startTime = System.nanoTime();
a.quietlyJoin(); // should be no-op a.quietlyJoin(); // should be no-op
assertTrue(millisElapsedSince(startTime) < SMALL_DELAY_MS); assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
} }
try { try {
@ -218,7 +215,7 @@ public class ForkJoinTaskTest extends JSR166TestCase {
} catch (Throwable fail) { threadUnexpectedException(fail); } } catch (Throwable fail) { threadUnexpectedException(fail); }
try { try {
a.get(5L, SECONDS); a.get(randomTimeout(), randomTimeUnit());
shouldThrow(); shouldThrow();
} catch (ExecutionException success) { } catch (ExecutionException success) {
assertSame(t.getClass(), success.getCause().getClass()); assertSame(t.getClass(), success.getCause().getClass());
@ -492,7 +489,7 @@ public class ForkJoinTaskTest extends JSR166TestCase {
AsyncFib f = new AsyncFib(8); AsyncFib f = new AsyncFib(8);
assertSame(f, f.fork()); assertSame(f, f.fork());
try { try {
f.get(5L, null); f.get(randomTimeout(), null);
shouldThrow(); shouldThrow();
} catch (NullPointerException success) {} } catch (NullPointerException success) {}
}}; }};
@ -1239,7 +1236,7 @@ public class ForkJoinTaskTest extends JSR166TestCase {
AsyncFib f = new AsyncFib(8); AsyncFib f = new AsyncFib(8);
assertSame(f, f.fork()); assertSame(f, f.fork());
try { try {
f.get(5L, null); f.get(randomTimeout(), null);
shouldThrow(); shouldThrow();
} catch (NullPointerException success) {} } catch (NullPointerException success) {}
}}; }};

View File

@ -35,7 +35,6 @@
import static java.util.concurrent.TimeUnit.MILLISECONDS; import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.concurrent.TimeUnit.NANOSECONDS; import static java.util.concurrent.TimeUnit.NANOSECONDS;
import static java.util.concurrent.TimeUnit.SECONDS;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -135,9 +134,7 @@ public class FutureTaskTest extends JSR166TestCase {
try { try {
assertSame(expected, f.get()); assertSame(expected, f.get());
} catch (Throwable fail) { threadUnexpectedException(fail); } assertSame(expected, f.get(randomTimeout(), randomTimeUnit()));
try {
assertSame(expected, f.get(5L, SECONDS));
} catch (Throwable fail) { threadUnexpectedException(fail); } } catch (Throwable fail) { threadUnexpectedException(fail); }
} }
@ -152,7 +149,7 @@ public class FutureTaskTest extends JSR166TestCase {
} catch (Throwable fail) { threadUnexpectedException(fail); } } catch (Throwable fail) { threadUnexpectedException(fail); }
try { try {
f.get(5L, SECONDS); f.get(randomTimeout(), randomTimeUnit());
shouldThrow(); shouldThrow();
} catch (CancellationException success) { } catch (CancellationException success) {
} catch (Throwable fail) { threadUnexpectedException(fail); } } catch (Throwable fail) { threadUnexpectedException(fail); }
@ -178,7 +175,7 @@ public class FutureTaskTest extends JSR166TestCase {
} catch (Throwable fail) { threadUnexpectedException(fail); } } catch (Throwable fail) { threadUnexpectedException(fail); }
try { try {
f.get(5L, SECONDS); f.get(randomTimeout(), randomTimeUnit());
shouldThrow(); shouldThrow();
} catch (ExecutionException success) { } catch (ExecutionException success) {
assertSame(t, success.getCause()); assertSame(t, success.getCause());
@ -444,6 +441,7 @@ public class FutureTaskTest extends JSR166TestCase {
delay(LONG_DELAY_MS); delay(LONG_DELAY_MS);
shouldThrow(); shouldThrow();
} catch (InterruptedException success) {} } catch (InterruptedException success) {}
assertFalse(Thread.interrupted());
}}); }});
Thread t = newStartedThread(task); Thread t = newStartedThread(task);

View File

@ -103,18 +103,24 @@ import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch; import java.util.concurrent.CountDownLatch;
import java.util.concurrent.CyclicBarrier; import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.ForkJoinPool; import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.Future; import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;
import java.util.concurrent.RecursiveAction; import java.util.concurrent.RecursiveAction;
import java.util.concurrent.RecursiveTask; import java.util.concurrent.RecursiveTask;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.RejectedExecutionHandler; import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.Semaphore; import java.util.concurrent.Semaphore;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.SynchronousQueue; import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadFactory; import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException; import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
@ -665,6 +671,33 @@ public class JSR166TestCase extends TestCase {
public static long MEDIUM_DELAY_MS; public static long MEDIUM_DELAY_MS;
public static long LONG_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 * Returns the shortest timed delay. This can be scaled up for
* slow machines using the jsr166.delay.factor system property, * slow machines using the jsr166.delay.factor system property,
@ -685,12 +718,17 @@ public class JSR166TestCase extends TestCase {
LONG_DELAY_MS = SHORT_DELAY_MS * 200; 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 * Returns a timeout in milliseconds to be used in tests that verify
* verify that operations block or time out. * 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() { static long timeoutMillis() {
return SHORT_DELAY_MS / 4; return TIMEOUT_DELAY_MS;
} }
/** /**
@ -1084,9 +1122,30 @@ public class JSR166TestCase extends TestCase {
if (sm != null) System.setSecurityManager(sm); if (sm != null) System.setSecurityManager(sm);
} }
/**
* 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 * Checks that thread does not terminate within the default
* millisecond delay of {@code timeoutMillis()}. * millisecond delay of {@code timeoutMillis()}.
* TODO: REMOVEME
*/ */
void assertThreadStaysAlive(Thread thread) { void assertThreadStaysAlive(Thread thread) {
assertThreadStaysAlive(thread, timeoutMillis()); assertThreadStaysAlive(thread, timeoutMillis());
@ -1094,6 +1153,7 @@ public class JSR166TestCase extends TestCase {
/** /**
* Checks that thread does not terminate within the given millisecond delay. * Checks that thread does not terminate within the given millisecond delay.
* TODO: REMOVEME
*/ */
void assertThreadStaysAlive(Thread thread, long millis) { void assertThreadStaysAlive(Thread thread, long millis) {
try { try {
@ -1108,6 +1168,7 @@ public class JSR166TestCase extends TestCase {
/** /**
* Checks that the threads do not terminate within the default * Checks that the threads do not terminate within the default
* millisecond delay of {@code timeoutMillis()}. * millisecond delay of {@code timeoutMillis()}.
* TODO: REMOVEME
*/ */
void assertThreadsStayAlive(Thread... threads) { void assertThreadsStayAlive(Thread... threads) {
assertThreadsStayAlive(timeoutMillis(), threads); assertThreadsStayAlive(timeoutMillis(), threads);
@ -1115,6 +1176,7 @@ public class JSR166TestCase extends TestCase {
/** /**
* Checks that the threads do not terminate within the given millisecond delay. * Checks that the threads do not terminate within the given millisecond delay.
* TODO: REMOVEME
*/ */
void assertThreadsStayAlive(long millis, Thread... threads) { void assertThreadsStayAlive(long millis, Thread... threads) {
try { try {
@ -1164,6 +1226,12 @@ public class JSR166TestCase extends TestCase {
fail("Should throw " + exceptionName); fail("Should throw " + exceptionName);
} }
/**
* 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. * The number of elements to place in collections, arrays, etc.
*/ */
@ -1633,6 +1701,14 @@ public class JSR166TestCase extends TestCase {
} }
} }
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. // * Spin-waits up to LONG_DELAY_MS until flag becomes true.
// */ // */
@ -1656,28 +1732,6 @@ public class JSR166TestCase extends TestCase {
public String call() { throw new NullPointerException(); } 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 { public class SmallPossiblyInterruptedRunnable extends CheckedRunnable {
protected void realRun() { protected void realRun() {
try { try {
@ -1686,25 +1740,6 @@ public class JSR166TestCase extends TestCase {
} }
} }
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) { public Runnable possiblyInterruptedRunnable(final long timeoutMillis) {
return new CheckedRunnable() { return new CheckedRunnable() {
protected void realRun() { protected void realRun() {
@ -1714,22 +1749,6 @@ public class JSR166TestCase extends TestCase {
}}; }};
} }
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 * For use as ThreadFactory in constructors
*/ */
@ -1743,59 +1762,6 @@ public class JSR166TestCase extends TestCase {
boolean isDone(); 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 static class TrackedNoOpRunnable implements Runnable {
public volatile boolean done = false; public volatile boolean done = false;
public void run() { public void run() {
@ -1803,17 +1769,6 @@ public class JSR166TestCase extends TestCase {
} }
} }
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 * Analog of CheckedRunnable for RecursiveAction
*/ */
@ -1880,7 +1835,7 @@ public class JSR166TestCase extends TestCase {
assertEquals(0, q.size()); assertEquals(0, q.size());
assertNull(q.peek()); assertNull(q.peek());
assertNull(q.poll()); assertNull(q.poll());
assertNull(q.poll(0, MILLISECONDS)); assertNull(q.poll(randomExpiredTimeout(), randomTimeUnit()));
assertEquals(q.toString(), "[]"); assertEquals(q.toString(), "[]");
assertTrue(Arrays.equals(q.toArray(), new Object[0])); assertTrue(Arrays.equals(q.toArray(), new Object[0]));
assertFalse(q.iterator().hasNext()); assertFalse(q.iterator().hasNext());
@ -2031,4 +1986,176 @@ public class JSR166TestCase extends TestCase {
static <T> void shuffle(T[] array) { static <T> void shuffle(T[] array) {
Collections.shuffle(Arrays.asList(array), ThreadLocalRandom.current()); 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());
}
} }

View File

@ -469,7 +469,7 @@ public class LinkedBlockingDequeTest extends JSR166TestCase {
} }
/** /**
* push succeeds if not full; throws ISE if full * push succeeds if not full; throws IllegalStateException if full
*/ */
public void testPush() { public void testPush() {
LinkedBlockingDeque q = new LinkedBlockingDeque(SIZE); LinkedBlockingDeque q = new LinkedBlockingDeque(SIZE);
@ -519,7 +519,7 @@ public class LinkedBlockingDequeTest extends JSR166TestCase {
} }
/** /**
* add succeeds if not full; throws ISE if full * add succeeds if not full; throws IllegalStateException if full
*/ */
public void testAdd() { public void testAdd() {
LinkedBlockingDeque q = new LinkedBlockingDeque(SIZE); LinkedBlockingDeque q = new LinkedBlockingDeque(SIZE);
@ -533,7 +533,7 @@ public class LinkedBlockingDequeTest extends JSR166TestCase {
} }
/** /**
* addAll(this) throws IAE * addAll(this) throws IllegalArgumentException
*/ */
public void testAddAllSelf() { public void testAddAllSelf() {
LinkedBlockingDeque q = populatedDeque(SIZE); LinkedBlockingDeque q = populatedDeque(SIZE);
@ -631,7 +631,7 @@ public class LinkedBlockingDequeTest extends JSR166TestCase {
}}); }});
await(pleaseInterrupt); await(pleaseInterrupt);
assertThreadStaysAlive(t); assertThreadBlocks(t, Thread.State.WAITING);
t.interrupt(); t.interrupt();
awaitTermination(t); awaitTermination(t);
assertEquals(SIZE, q.size()); assertEquals(SIZE, q.size());
@ -653,6 +653,13 @@ public class LinkedBlockingDequeTest extends JSR166TestCase {
pleaseTake.countDown(); pleaseTake.countDown();
q.put(86); q.put(86);
Thread.currentThread().interrupt();
try {
q.put(99);
shouldThrow();
} catch (InterruptedException success) {}
assertFalse(Thread.interrupted());
pleaseInterrupt.countDown(); pleaseInterrupt.countDown();
try { try {
q.put(99); q.put(99);
@ -666,7 +673,7 @@ public class LinkedBlockingDequeTest extends JSR166TestCase {
assertEquals(0, q.take()); assertEquals(0, q.take());
await(pleaseInterrupt); await(pleaseInterrupt);
assertThreadStaysAlive(t); assertThreadBlocks(t, Thread.State.WAITING);
t.interrupt(); t.interrupt();
awaitTermination(t); awaitTermination(t);
assertEquals(0, q.remainingCapacity()); assertEquals(0, q.remainingCapacity());
@ -675,7 +682,7 @@ public class LinkedBlockingDequeTest extends JSR166TestCase {
/** /**
* timed offer times out if full and elements not taken * 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 LinkedBlockingDeque q = new LinkedBlockingDeque(2);
final CountDownLatch pleaseInterrupt = new CountDownLatch(1); final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
Thread t = newStartedThread(new CheckedRunnable() { Thread t = newStartedThread(new CheckedRunnable() {
@ -685,15 +692,24 @@ public class LinkedBlockingDequeTest extends JSR166TestCase {
long startTime = System.nanoTime(); long startTime = System.nanoTime();
assertFalse(q.offer(new Object(), timeoutMillis(), MILLISECONDS)); assertFalse(q.offer(new Object(), timeoutMillis(), MILLISECONDS));
assertTrue(millisElapsedSince(startTime) >= timeoutMillis()); 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(); pleaseInterrupt.countDown();
try { try {
q.offer(new Object(), 2 * LONG_DELAY_MS, MILLISECONDS); q.offer(new Object(), 2 * LONG_DELAY_MS, MILLISECONDS);
shouldThrow(); shouldThrow();
} catch (InterruptedException success) {} } catch (InterruptedException success) {}
assertFalse(Thread.interrupted());
}}); }});
await(pleaseInterrupt); await(pleaseInterrupt);
assertThreadStaysAlive(t); assertThreadBlocks(t, Thread.State.TIMED_WAITING);
t.interrupt(); t.interrupt();
awaitTermination(t); awaitTermination(t);
} }
@ -716,9 +732,7 @@ public class LinkedBlockingDequeTest extends JSR166TestCase {
final CountDownLatch pleaseInterrupt = new CountDownLatch(1); final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
Thread t = newStartedThread(new CheckedRunnable() { Thread t = newStartedThread(new CheckedRunnable() {
public void realRun() throws InterruptedException { public void realRun() throws InterruptedException {
for (int i = 0; i < SIZE; ++i) { for (int i = 0; i < SIZE; i++) assertEquals(i, q.take());
assertEquals(i, q.take());
}
Thread.currentThread().interrupt(); Thread.currentThread().interrupt();
try { try {
@ -736,7 +750,7 @@ public class LinkedBlockingDequeTest extends JSR166TestCase {
}}); }});
await(pleaseInterrupt); await(pleaseInterrupt);
assertThreadStaysAlive(t); assertThreadBlocks(t, Thread.State.WAITING);
t.interrupt(); t.interrupt();
awaitTermination(t); awaitTermination(t);
} }
@ -785,24 +799,32 @@ public class LinkedBlockingDequeTest extends JSR166TestCase {
*/ */
public void testInterruptedTimedPoll() throws InterruptedException { public void testInterruptedTimedPoll() throws InterruptedException {
final BlockingQueue<Integer> q = populatedDeque(SIZE); final BlockingQueue<Integer> q = populatedDeque(SIZE);
final CountDownLatch aboutToWait = new CountDownLatch(1); final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
Thread t = newStartedThread(new CheckedRunnable() { Thread t = newStartedThread(new CheckedRunnable() {
public void realRun() throws InterruptedException { public void realRun() throws InterruptedException {
long startTime = System.nanoTime(); 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)); assertEquals(i, (int) q.poll(LONG_DELAY_MS, MILLISECONDS));
}
aboutToWait.countDown(); Thread.currentThread().interrupt();
try { try {
q.poll(LONG_DELAY_MS, MILLISECONDS); q.poll(LONG_DELAY_MS, MILLISECONDS);
shouldThrow(); shouldThrow();
} catch (InterruptedException success) { } catch (InterruptedException success) {}
assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS); 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); await(pleaseInterrupt);
waitForThreadToEnterWaitState(t); assertThreadBlocks(t, Thread.State.TIMED_WAITING);
t.interrupt(); t.interrupt();
awaitTermination(t); awaitTermination(t);
checkEmpty(q); checkEmpty(q);
@ -861,7 +883,7 @@ public class LinkedBlockingDequeTest extends JSR166TestCase {
}}); }});
await(pleaseInterrupt); await(pleaseInterrupt);
assertThreadStaysAlive(t); assertThreadBlocks(t, Thread.State.WAITING);
t.interrupt(); t.interrupt();
awaitTermination(t); awaitTermination(t);
assertEquals(SIZE, q.size()); assertEquals(SIZE, q.size());
@ -896,7 +918,7 @@ public class LinkedBlockingDequeTest extends JSR166TestCase {
assertEquals(capacity - 1, q.take()); assertEquals(capacity - 1, q.take());
await(pleaseInterrupt); await(pleaseInterrupt);
assertThreadStaysAlive(t); assertThreadBlocks(t, Thread.State.WAITING);
t.interrupt(); t.interrupt();
awaitTermination(t); awaitTermination(t);
assertEquals(0, q.remainingCapacity()); assertEquals(0, q.remainingCapacity());
@ -905,7 +927,7 @@ public class LinkedBlockingDequeTest extends JSR166TestCase {
/** /**
* timed offerFirst times out if full and elements not taken * 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 LinkedBlockingDeque q = new LinkedBlockingDeque(2);
final CountDownLatch pleaseInterrupt = new CountDownLatch(1); final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
Thread t = newStartedThread(new CheckedRunnable() { Thread t = newStartedThread(new CheckedRunnable() {
@ -915,15 +937,24 @@ public class LinkedBlockingDequeTest extends JSR166TestCase {
long startTime = System.nanoTime(); long startTime = System.nanoTime();
assertFalse(q.offerFirst(new Object(), timeoutMillis(), MILLISECONDS)); assertFalse(q.offerFirst(new Object(), timeoutMillis(), MILLISECONDS));
assertTrue(millisElapsedSince(startTime) >= timeoutMillis()); 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(); pleaseInterrupt.countDown();
try { try {
q.offerFirst(new Object(), 2 * LONG_DELAY_MS, MILLISECONDS); q.offerFirst(new Object(), 2 * LONG_DELAY_MS, MILLISECONDS);
shouldThrow(); shouldThrow();
} catch (InterruptedException success) {} } catch (InterruptedException success) {}
assertFalse(Thread.interrupted());
}}); }});
await(pleaseInterrupt); await(pleaseInterrupt);
assertThreadStaysAlive(t); assertThreadBlocks(t, Thread.State.TIMED_WAITING);
t.interrupt(); t.interrupt();
awaitTermination(t); awaitTermination(t);
} }
@ -955,7 +986,7 @@ public class LinkedBlockingDequeTest extends JSR166TestCase {
}}); }});
await(threadStarted); await(threadStarted);
assertThreadStaysAlive(t); assertThreadBlocks(t, Thread.State.WAITING);
t.interrupt(); t.interrupt();
awaitTermination(t); awaitTermination(t);
} }
@ -996,7 +1027,7 @@ public class LinkedBlockingDequeTest extends JSR166TestCase {
}}); }});
await(threadStarted); await(threadStarted);
assertThreadStaysAlive(t); assertThreadBlocks(t, Thread.State.WAITING);
t.interrupt(); t.interrupt();
awaitTermination(t); awaitTermination(t);
} }
@ -1028,9 +1059,7 @@ public class LinkedBlockingDequeTest extends JSR166TestCase {
final CountDownLatch pleaseInterrupt = new CountDownLatch(1); final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
Thread t = newStartedThread(new CheckedRunnable() { Thread t = newStartedThread(new CheckedRunnable() {
public void realRun() throws InterruptedException { public void realRun() throws InterruptedException {
for (int i = 0; i < SIZE; ++i) { for (int i = 0; i < SIZE; i++) assertEquals(i, q.takeFirst());
assertEquals(i, q.takeFirst());
}
Thread.currentThread().interrupt(); Thread.currentThread().interrupt();
try { try {
@ -1048,7 +1077,7 @@ public class LinkedBlockingDequeTest extends JSR166TestCase {
}}); }});
await(pleaseInterrupt); await(pleaseInterrupt);
assertThreadStaysAlive(t); assertThreadBlocks(t, Thread.State.WAITING);
t.interrupt(); t.interrupt();
awaitTermination(t); awaitTermination(t);
} }
@ -1090,9 +1119,8 @@ public class LinkedBlockingDequeTest extends JSR166TestCase {
Thread t = newStartedThread(new CheckedRunnable() { Thread t = newStartedThread(new CheckedRunnable() {
public void realRun() throws InterruptedException { public void realRun() throws InterruptedException {
long startTime = System.nanoTime(); 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)); assertEquals(i, q.pollFirst(LONG_DELAY_MS, MILLISECONDS));
}
Thread.currentThread().interrupt(); Thread.currentThread().interrupt();
try { try {
@ -1107,11 +1135,12 @@ public class LinkedBlockingDequeTest extends JSR166TestCase {
shouldThrow(); shouldThrow();
} catch (InterruptedException success) {} } catch (InterruptedException success) {}
assertFalse(Thread.interrupted()); assertFalse(Thread.interrupted());
assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS); assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
}}); }});
await(pleaseInterrupt); await(pleaseInterrupt);
assertThreadStaysAlive(t); assertThreadBlocks(t, Thread.State.TIMED_WAITING);
t.interrupt(); t.interrupt();
awaitTermination(t); awaitTermination(t);
} }
@ -1144,6 +1173,7 @@ public class LinkedBlockingDequeTest extends JSR166TestCase {
q.pollFirst(LONG_DELAY_MS, MILLISECONDS); q.pollFirst(LONG_DELAY_MS, MILLISECONDS);
shouldThrow(); shouldThrow();
} catch (InterruptedException success) {} } catch (InterruptedException success) {}
assertFalse(Thread.interrupted());
assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS); assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
}}); }});
@ -1152,7 +1182,7 @@ public class LinkedBlockingDequeTest extends JSR166TestCase {
assertTrue(q.offerFirst(zero, LONG_DELAY_MS, MILLISECONDS)); assertTrue(q.offerFirst(zero, LONG_DELAY_MS, MILLISECONDS));
assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS); assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
barrier.await(); barrier.await();
assertThreadStaysAlive(t); assertThreadBlocks(t, Thread.State.TIMED_WAITING);
t.interrupt(); t.interrupt();
awaitTermination(t); awaitTermination(t);
} }
@ -1210,7 +1240,7 @@ public class LinkedBlockingDequeTest extends JSR166TestCase {
}}); }});
await(pleaseInterrupt); await(pleaseInterrupt);
assertThreadStaysAlive(t); assertThreadBlocks(t, Thread.State.WAITING);
t.interrupt(); t.interrupt();
awaitTermination(t); awaitTermination(t);
assertEquals(SIZE, q.size()); assertEquals(SIZE, q.size());
@ -1232,6 +1262,13 @@ public class LinkedBlockingDequeTest extends JSR166TestCase {
pleaseTake.countDown(); pleaseTake.countDown();
q.putLast(86); q.putLast(86);
Thread.currentThread().interrupt();
try {
q.putLast(99);
shouldThrow();
} catch (InterruptedException success) {}
assertFalse(Thread.interrupted());
pleaseInterrupt.countDown(); pleaseInterrupt.countDown();
try { try {
q.putLast(99); q.putLast(99);
@ -1245,7 +1282,7 @@ public class LinkedBlockingDequeTest extends JSR166TestCase {
assertEquals(0, q.take()); assertEquals(0, q.take());
await(pleaseInterrupt); await(pleaseInterrupt);
assertThreadStaysAlive(t); assertThreadBlocks(t, Thread.State.WAITING);
t.interrupt(); t.interrupt();
awaitTermination(t); awaitTermination(t);
assertEquals(0, q.remainingCapacity()); assertEquals(0, q.remainingCapacity());
@ -1254,7 +1291,7 @@ public class LinkedBlockingDequeTest extends JSR166TestCase {
/** /**
* timed offerLast times out if full and elements not taken * 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 LinkedBlockingDeque q = new LinkedBlockingDeque(2);
final CountDownLatch pleaseInterrupt = new CountDownLatch(1); final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
Thread t = newStartedThread(new CheckedRunnable() { Thread t = newStartedThread(new CheckedRunnable() {
@ -1264,6 +1301,13 @@ public class LinkedBlockingDequeTest extends JSR166TestCase {
long startTime = System.nanoTime(); long startTime = System.nanoTime();
assertFalse(q.offerLast(new Object(), timeoutMillis(), MILLISECONDS)); assertFalse(q.offerLast(new Object(), timeoutMillis(), MILLISECONDS));
assertTrue(millisElapsedSince(startTime) >= timeoutMillis()); assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
Thread.currentThread().interrupt();
try {
q.offerLast(new Object(), 2 * LONG_DELAY_MS, MILLISECONDS);
shouldThrow();
} catch (InterruptedException success) {}
pleaseInterrupt.countDown(); pleaseInterrupt.countDown();
try { try {
q.offerLast(new Object(), 2 * LONG_DELAY_MS, MILLISECONDS); q.offerLast(new Object(), 2 * LONG_DELAY_MS, MILLISECONDS);
@ -1272,7 +1316,7 @@ public class LinkedBlockingDequeTest extends JSR166TestCase {
}}); }});
await(pleaseInterrupt); await(pleaseInterrupt);
assertThreadStaysAlive(t); assertThreadBlocks(t, Thread.State.TIMED_WAITING);
t.interrupt(); t.interrupt();
awaitTermination(t); awaitTermination(t);
} }
@ -1295,9 +1339,8 @@ public class LinkedBlockingDequeTest extends JSR166TestCase {
final CountDownLatch pleaseInterrupt = new CountDownLatch(1); final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
Thread t = newStartedThread(new CheckedRunnable() { Thread t = newStartedThread(new CheckedRunnable() {
public void realRun() throws InterruptedException { 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()); assertEquals(SIZE - i - 1, q.takeLast());
}
Thread.currentThread().interrupt(); Thread.currentThread().interrupt();
try { try {
@ -1315,7 +1358,7 @@ public class LinkedBlockingDequeTest extends JSR166TestCase {
}}); }});
await(pleaseInterrupt); await(pleaseInterrupt);
assertThreadStaysAlive(t); assertThreadBlocks(t, Thread.State.WAITING);
t.interrupt(); t.interrupt();
awaitTermination(t); awaitTermination(t);
} }
@ -1357,10 +1400,9 @@ public class LinkedBlockingDequeTest extends JSR166TestCase {
Thread t = newStartedThread(new CheckedRunnable() { Thread t = newStartedThread(new CheckedRunnable() {
public void realRun() throws InterruptedException { public void realRun() throws InterruptedException {
long startTime = System.nanoTime(); long startTime = System.nanoTime();
for (int i = 0; i < SIZE; ++i) { for (int i = 0; i < SIZE; i++)
assertEquals(SIZE - i - 1, assertEquals(SIZE - i - 1,
q.pollLast(LONG_DELAY_MS, MILLISECONDS)); q.pollLast(LONG_DELAY_MS, MILLISECONDS));
}
Thread.currentThread().interrupt(); Thread.currentThread().interrupt();
try { try {
@ -1380,7 +1422,7 @@ public class LinkedBlockingDequeTest extends JSR166TestCase {
}}); }});
await(pleaseInterrupt); await(pleaseInterrupt);
assertThreadStaysAlive(t); assertThreadBlocks(t, Thread.State.TIMED_WAITING);
t.interrupt(); t.interrupt();
awaitTermination(t); awaitTermination(t);
checkEmpty(q); checkEmpty(q);
@ -1426,7 +1468,7 @@ public class LinkedBlockingDequeTest extends JSR166TestCase {
assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS); assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
barrier.await(); barrier.await();
assertThreadStaysAlive(t); assertThreadBlocks(t, Thread.State.TIMED_WAITING);
t.interrupt(); t.interrupt();
awaitTermination(t); awaitTermination(t);
} }

View File

@ -319,7 +319,7 @@ public class LinkedBlockingQueueTest extends JSR166TestCase {
}}); }});
await(pleaseInterrupt); await(pleaseInterrupt);
assertThreadStaysAlive(t); assertThreadBlocks(t, Thread.State.WAITING);
t.interrupt(); t.interrupt();
awaitTermination(t); awaitTermination(t);
assertEquals(SIZE, q.size()); assertEquals(SIZE, q.size());
@ -341,6 +341,13 @@ public class LinkedBlockingQueueTest extends JSR166TestCase {
pleaseTake.countDown(); pleaseTake.countDown();
q.put(86); q.put(86);
Thread.currentThread().interrupt();
try {
q.put(99);
shouldThrow();
} catch (InterruptedException success) {}
assertFalse(Thread.interrupted());
pleaseInterrupt.countDown(); pleaseInterrupt.countDown();
try { try {
q.put(99); q.put(99);
@ -354,7 +361,7 @@ public class LinkedBlockingQueueTest extends JSR166TestCase {
assertEquals(0, q.take()); assertEquals(0, q.take());
await(pleaseInterrupt); await(pleaseInterrupt);
assertThreadStaysAlive(t); assertThreadBlocks(t, Thread.State.WAITING);
t.interrupt(); t.interrupt();
awaitTermination(t); awaitTermination(t);
assertEquals(0, q.remainingCapacity()); assertEquals(0, q.remainingCapacity());
@ -370,18 +377,28 @@ public class LinkedBlockingQueueTest extends JSR166TestCase {
public void realRun() throws InterruptedException { public void realRun() throws InterruptedException {
q.put(new Object()); q.put(new Object());
q.put(new Object()); q.put(new Object());
long startTime = System.nanoTime(); long startTime = System.nanoTime();
assertFalse(q.offer(new Object(), timeoutMillis(), MILLISECONDS)); assertFalse(q.offer(new Object(), timeoutMillis(), MILLISECONDS));
assertTrue(millisElapsedSince(startTime) >= timeoutMillis()); 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(); pleaseInterrupt.countDown();
try { try {
q.offer(new Object(), 2 * LONG_DELAY_MS, MILLISECONDS); q.offer(new Object(), 2 * LONG_DELAY_MS, MILLISECONDS);
shouldThrow(); shouldThrow();
} catch (InterruptedException success) {} } catch (InterruptedException success) {}
assertFalse(Thread.interrupted());
}}); }});
await(pleaseInterrupt); await(pleaseInterrupt);
assertThreadStaysAlive(t); assertThreadBlocks(t, Thread.State.TIMED_WAITING);
t.interrupt(); t.interrupt();
awaitTermination(t); awaitTermination(t);
} }
@ -404,9 +421,7 @@ public class LinkedBlockingQueueTest extends JSR166TestCase {
final CountDownLatch pleaseInterrupt = new CountDownLatch(1); final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
Thread t = newStartedThread(new CheckedRunnable() { Thread t = newStartedThread(new CheckedRunnable() {
public void realRun() throws InterruptedException { public void realRun() throws InterruptedException {
for (int i = 0; i < SIZE; ++i) { for (int i = 0; i < SIZE; i++) assertEquals(i, q.take());
assertEquals(i, q.take());
}
Thread.currentThread().interrupt(); Thread.currentThread().interrupt();
try { try {
@ -424,7 +439,7 @@ public class LinkedBlockingQueueTest extends JSR166TestCase {
}}); }});
await(pleaseInterrupt); await(pleaseInterrupt);
assertThreadStaysAlive(t); assertThreadBlocks(t, Thread.State.WAITING);
t.interrupt(); t.interrupt();
awaitTermination(t); awaitTermination(t);
} }
@ -473,24 +488,32 @@ public class LinkedBlockingQueueTest extends JSR166TestCase {
*/ */
public void testInterruptedTimedPoll() throws InterruptedException { public void testInterruptedTimedPoll() throws InterruptedException {
final BlockingQueue<Integer> q = populatedQueue(SIZE); final BlockingQueue<Integer> q = populatedQueue(SIZE);
final CountDownLatch aboutToWait = new CountDownLatch(1); final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
Thread t = newStartedThread(new CheckedRunnable() { Thread t = newStartedThread(new CheckedRunnable() {
public void realRun() throws InterruptedException { public void realRun() throws InterruptedException {
long startTime = System.nanoTime(); 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)); assertEquals(i, (int) q.poll(LONG_DELAY_MS, MILLISECONDS));
}
aboutToWait.countDown(); Thread.currentThread().interrupt();
try { try {
q.poll(LONG_DELAY_MS, MILLISECONDS); q.poll(LONG_DELAY_MS, MILLISECONDS);
shouldThrow(); shouldThrow();
} catch (InterruptedException success) { } catch (InterruptedException success) {}
assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS); 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); await(pleaseInterrupt);
waitForThreadToEnterWaitState(t); assertThreadBlocks(t, Thread.State.TIMED_WAITING);
t.interrupt(); t.interrupt();
awaitTermination(t); awaitTermination(t);
checkEmpty(q); checkEmpty(q);

View File

@ -236,9 +236,7 @@ public class LinkedTransferQueueTest extends JSR166TestCase {
final CountDownLatch pleaseInterrupt = new CountDownLatch(1); final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
Thread t = newStartedThread(new CheckedRunnable() { Thread t = newStartedThread(new CheckedRunnable() {
public void realRun() throws InterruptedException { public void realRun() throws InterruptedException {
for (int i = 0; i < SIZE; ++i) { for (int i = 0; i < SIZE; i++) assertEquals(i, q.take());
assertEquals(i, q.take());
}
Thread.currentThread().interrupt(); Thread.currentThread().interrupt();
try { try {
@ -256,7 +254,7 @@ public class LinkedTransferQueueTest extends JSR166TestCase {
}}); }});
await(pleaseInterrupt); await(pleaseInterrupt);
assertThreadStaysAlive(t); assertThreadBlocks(t, Thread.State.WAITING);
t.interrupt(); t.interrupt();
awaitTermination(t); awaitTermination(t);
} }
@ -307,22 +305,32 @@ public class LinkedTransferQueueTest extends JSR166TestCase {
*/ */
public void testInterruptedTimedPoll() throws InterruptedException { public void testInterruptedTimedPoll() throws InterruptedException {
final BlockingQueue<Integer> q = populatedQueue(SIZE); final BlockingQueue<Integer> q = populatedQueue(SIZE);
final CountDownLatch aboutToWait = new CountDownLatch(1); final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
Thread t = newStartedThread(new CheckedRunnable() { Thread t = newStartedThread(new CheckedRunnable() {
public void realRun() throws InterruptedException { public void realRun() throws InterruptedException {
long startTime = System.nanoTime(); 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)); assertEquals(i, (int) q.poll(LONG_DELAY_MS, MILLISECONDS));
aboutToWait.countDown();
Thread.currentThread().interrupt();
try { try {
q.poll(LONG_DELAY_MS, MILLISECONDS); q.poll(LONG_DELAY_MS, MILLISECONDS);
shouldThrow(); shouldThrow();
} catch (InterruptedException success) {} } 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); assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
}}); }});
await(aboutToWait); await(pleaseInterrupt);
waitForThreadToEnterWaitState(t); assertThreadBlocks(t, Thread.State.TIMED_WAITING);
t.interrupt(); t.interrupt();
awaitTermination(t); awaitTermination(t);
checkEmpty(q); checkEmpty(q);
@ -344,6 +352,7 @@ public class LinkedTransferQueueTest extends JSR166TestCase {
q.poll(LONG_DELAY_MS, MILLISECONDS); q.poll(LONG_DELAY_MS, MILLISECONDS);
shouldThrow(); shouldThrow();
} catch (InterruptedException success) {} } catch (InterruptedException success) {}
assertFalse(Thread.interrupted());
assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS); assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
}}); }});
@ -990,7 +999,7 @@ public class LinkedTransferQueueTest extends JSR166TestCase {
}}); }});
await(pleaseInterrupt); await(pleaseInterrupt);
assertThreadStaysAlive(t); assertThreadBlocks(t, Thread.State.TIMED_WAITING);
t.interrupt(); t.interrupt();
awaitTermination(t); awaitTermination(t);
checkEmpty(q); checkEmpty(q);

View File

@ -71,9 +71,7 @@ public class LockSupportTest extends JSR166TestCase {
void park() { void park() {
LockSupport.park(); LockSupport.park();
} }
void park(long millis) { Thread.State parkedState() { return Thread.State.WAITING; }
throw new UnsupportedOperationException();
}
}, },
parkUntil() { parkUntil() {
void park(long millis) { void park(long millis) {
@ -89,9 +87,7 @@ public class LockSupportTest extends JSR166TestCase {
void park() { void park() {
LockSupport.park(theBlocker()); LockSupport.park(theBlocker());
} }
void park(long millis) { Thread.State parkedState() { return Thread.State.WAITING; }
throw new UnsupportedOperationException();
}
}, },
parkUntilBlocker() { parkUntilBlocker() {
void park(long millis) { void park(long millis) {
@ -106,7 +102,10 @@ public class LockSupportTest extends JSR166TestCase {
}; };
void park() { park(2 * LONG_DELAY_MS); } 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. */ /** Returns a deadline to use with parkUntil. */
long deadline(long millis) { long deadline(long millis) {
@ -213,14 +212,16 @@ public class LockSupportTest extends JSR166TestCase {
Thread t = newStartedThread(new CheckedRunnable() { Thread t = newStartedThread(new CheckedRunnable() {
public void realRun() { public void realRun() {
pleaseInterrupt.countDown(); pleaseInterrupt.countDown();
do { for (int tries = MAX_SPURIOUS_WAKEUPS; tries-->0; ) {
parkMethod.park(); parkMethod.park();
// park may return spuriously if (Thread.interrupted())
} while (! Thread.currentThread().isInterrupted()); return;
}
fail("too many consecutive spurious wakeups?");
}}); }});
await(pleaseInterrupt); await(pleaseInterrupt);
assertThreadStaysAlive(t); assertThreadBlocks(t, parkMethod.parkedState());
t.interrupt(); t.interrupt();
awaitTermination(t); awaitTermination(t);
} }
@ -248,20 +249,17 @@ public class LockSupportTest extends JSR166TestCase {
} }
public void testParkAfterInterrupt(final ParkMethod parkMethod) { public void testParkAfterInterrupt(final ParkMethod parkMethod) {
final CountDownLatch pleaseInterrupt = new CountDownLatch(1); final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
final AtomicBoolean pleasePark = new AtomicBoolean(false);
Thread t = newStartedThread(new CheckedRunnable() { Thread t = newStartedThread(new CheckedRunnable() {
public void realRun() throws Exception { public void realRun() throws Exception {
pleaseInterrupt.countDown(); pleaseInterrupt.countDown();
while (!pleasePark.get()) while (!Thread.currentThread().isInterrupted())
Thread.yield(); Thread.yield();
assertTrue(Thread.currentThread().isInterrupted());
parkMethod.park(); parkMethod.park();
assertTrue(Thread.currentThread().isInterrupted()); assertTrue(Thread.interrupted());
}}); }});
await(pleaseInterrupt); await(pleaseInterrupt);
t.interrupt(); t.interrupt();
pleasePark.set(true);
awaitTermination(t); awaitTermination(t);
} }
@ -283,13 +281,13 @@ public class LockSupportTest extends JSR166TestCase {
public void testParkTimesOut(final ParkMethod parkMethod) { public void testParkTimesOut(final ParkMethod parkMethod) {
Thread t = newStartedThread(new CheckedRunnable() { Thread t = newStartedThread(new CheckedRunnable() {
public void realRun() { public void realRun() {
for (;;) { for (int tries = MAX_SPURIOUS_WAKEUPS; tries-->0; ) {
long startTime = System.nanoTime(); long startTime = System.nanoTime();
parkMethod.park(timeoutMillis()); parkMethod.park(timeoutMillis());
// park may return spuriously
if (millisElapsedSince(startTime) >= timeoutMillis()) if (millisElapsedSince(startTime) >= timeoutMillis())
return; return;
} }
fail("too many consecutive spurious wakeups?");
}}); }});
awaitTermination(t); awaitTermination(t);
@ -323,12 +321,14 @@ public class LockSupportTest extends JSR166TestCase {
public void realRun() { public void realRun() {
Thread t = Thread.currentThread(); Thread t = Thread.currentThread();
started.countDown(); started.countDown();
do { for (int tries = MAX_SPURIOUS_WAKEUPS; tries-->0; ) {
assertNull(LockSupport.getBlocker(t)); assertNull(LockSupport.getBlocker(t));
parkMethod.park(); parkMethod.park();
assertNull(LockSupport.getBlocker(t)); assertNull(LockSupport.getBlocker(t));
// park may return spuriously if (Thread.interrupted())
} while (! Thread.currentThread().isInterrupted()); return;
}
fail("too many consecutive spurious wakeups?");
}}); }});
long startTime = System.nanoTime(); long startTime = System.nanoTime();
@ -344,6 +344,8 @@ public class LockSupportTest extends JSR166TestCase {
assertNull(x); // ok assertNull(x); // ok
if (millisElapsedSince(startTime) > LONG_DELAY_MS) if (millisElapsedSince(startTime) > LONG_DELAY_MS)
fail("timed out"); fail("timed out");
if (t.getState() == Thread.State.TERMINATED)
break;
Thread.yield(); Thread.yield();
} }
} }

View File

@ -34,6 +34,7 @@
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Phaser; import java.util.concurrent.Phaser;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.atomic.LongAccumulator; import java.util.concurrent.atomic.LongAccumulator;
import junit.framework.Test; import junit.framework.Test;
@ -48,135 +49,124 @@ public class LongAccumulatorTest extends JSR166TestCase {
} }
/** /**
* default constructed initializes to zero * new instance initialized to supplied identity
*/ */
public void testConstructor() { public void testConstructor() {
LongAccumulator ai = new LongAccumulator(Long::max, 0L); for (long identity : new long[] { Long.MIN_VALUE, 0, Long.MAX_VALUE })
assertEquals(0, ai.get()); assertEquals(identity,
new LongAccumulator(Long::max, identity).get());
} }
/** /**
* accumulate accumulates given value to current, and get returns current value * accumulate accumulates given value to current, and get returns current value
*/ */
public void testAccumulateAndGet() { public void testAccumulateAndGet() {
LongAccumulator ai = new LongAccumulator(Long::max, 0L); LongAccumulator acc = new LongAccumulator(Long::max, 0L);
ai.accumulate(2); acc.accumulate(2);
assertEquals(2, ai.get()); assertEquals(2, acc.get());
ai.accumulate(-4); acc.accumulate(-4);
assertEquals(2, ai.get()); assertEquals(2, acc.get());
ai.accumulate(4); acc.accumulate(4);
assertEquals(4, ai.get()); assertEquals(4, acc.get());
} }
/** /**
* reset() causes subsequent get() to return zero * reset() causes subsequent get() to return zero
*/ */
public void testReset() { public void testReset() {
LongAccumulator ai = new LongAccumulator(Long::max, 0L); LongAccumulator acc = new LongAccumulator(Long::max, 0L);
ai.accumulate(2); acc.accumulate(2);
assertEquals(2, ai.get()); assertEquals(2, acc.get());
ai.reset(); acc.reset();
assertEquals(0, ai.get()); assertEquals(0, acc.get());
} }
/** /**
* getThenReset() returns current value; subsequent get() returns zero * getThenReset() returns current value; subsequent get() returns zero
*/ */
public void testGetThenReset() { public void testGetThenReset() {
LongAccumulator ai = new LongAccumulator(Long::max, 0L); LongAccumulator acc = new LongAccumulator(Long::max, 0L);
ai.accumulate(2); acc.accumulate(2);
assertEquals(2, ai.get()); assertEquals(2, acc.get());
assertEquals(2, ai.getThenReset()); assertEquals(2, acc.getThenReset());
assertEquals(0, ai.get()); assertEquals(0, acc.get());
} }
/** /**
* toString returns current value. * toString returns current value.
*/ */
public void testToString() { public void testToString() {
LongAccumulator ai = new LongAccumulator(Long::max, 0L); LongAccumulator acc = new LongAccumulator(Long::max, 0L);
assertEquals("0", ai.toString()); assertEquals("0", acc.toString());
ai.accumulate(1); acc.accumulate(1);
assertEquals(Long.toString(1), ai.toString()); assertEquals(Long.toString(1), acc.toString());
} }
/** /**
* intValue returns current value. * intValue returns current value.
*/ */
public void testIntValue() { public void testIntValue() {
LongAccumulator ai = new LongAccumulator(Long::max, 0L); LongAccumulator acc = new LongAccumulator(Long::max, 0L);
assertEquals(0, ai.intValue()); assertEquals(0, acc.intValue());
ai.accumulate(1); acc.accumulate(1);
assertEquals(1, ai.intValue()); assertEquals(1, acc.intValue());
} }
/** /**
* longValue returns current value. * longValue returns current value.
*/ */
public void testLongValue() { public void testLongValue() {
LongAccumulator ai = new LongAccumulator(Long::max, 0L); LongAccumulator acc = new LongAccumulator(Long::max, 0L);
assertEquals(0, ai.longValue()); assertEquals(0, acc.longValue());
ai.accumulate(1); acc.accumulate(1);
assertEquals(1, ai.longValue()); assertEquals(1, acc.longValue());
} }
/** /**
* floatValue returns current value. * floatValue returns current value.
*/ */
public void testFloatValue() { public void testFloatValue() {
LongAccumulator ai = new LongAccumulator(Long::max, 0L); LongAccumulator acc = new LongAccumulator(Long::max, 0L);
assertEquals(0.0f, ai.floatValue()); assertEquals(0.0f, acc.floatValue());
ai.accumulate(1); acc.accumulate(1);
assertEquals(1.0f, ai.floatValue()); assertEquals(1.0f, acc.floatValue());
} }
/** /**
* doubleValue returns current value. * doubleValue returns current value.
*/ */
public void testDoubleValue() { public void testDoubleValue() {
LongAccumulator ai = new LongAccumulator(Long::max, 0L); LongAccumulator acc = new LongAccumulator(Long::max, 0L);
assertEquals(0.0, ai.doubleValue()); assertEquals(0.0, acc.doubleValue());
ai.accumulate(1); acc.accumulate(1);
assertEquals(1.0, ai.doubleValue()); assertEquals(1.0, acc.doubleValue());
} }
/** /**
* accumulates by multiple threads produce correct result * accumulates by multiple threads produce correct result
*/ */
public void testAccumulateAndGetMT() { public void testAccumulateAndGetMT() {
final int incs = 1000000; final LongAccumulator acc
final int nthreads = 4; = new LongAccumulator((x, y) -> x + y, 0L);
final ExecutorService pool = Executors.newCachedThreadPool(); final int nThreads = ThreadLocalRandom.current().nextInt(1, 5);
LongAccumulator a = new LongAccumulator(Long::max, 0L); final Phaser phaser = new Phaser(nThreads + 1);
Phaser phaser = new Phaser(nthreads + 1); final int incs = 1_000_000;
for (int i = 0; i < nthreads; ++i) final long total = nThreads * incs/2L * (incs - 1); // Gauss
pool.execute(new AccTask(a, phaser, incs)); final Runnable task = () -> {
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() {
phaser.arriveAndAwaitAdvance(); phaser.arriveAndAwaitAdvance();
LongAccumulator a = acc; for (int i = 0; i < incs; i++) {
for (int i = 0; i < incs; ++i) acc.accumulate((long) i);
a.accumulate(i); assertTrue(acc.get() <= total);
result = a.get(); }
phaser.arrive(); 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());
} }
} }

View File

@ -520,7 +520,8 @@ public class PhaserTest extends JSR166TestCase {
await(pleaseInterrupt); await(pleaseInterrupt);
assertState(phaser, 0, 1, 1); assertState(phaser, 0, 1, 1);
assertThreadsStayAlive(t1, t2); assertThreadBlocks(t1, Thread.State.WAITING);
assertThreadBlocks(t2, Thread.State.TIMED_WAITING);
t1.interrupt(); t1.interrupt();
t2.interrupt(); t2.interrupt();
awaitTermination(t1); awaitTermination(t1);
@ -550,7 +551,7 @@ public class PhaserTest extends JSR166TestCase {
}}); }});
await(pleaseArrive); await(pleaseArrive);
waitForThreadToEnterWaitState(t); assertThreadBlocks(t, Thread.State.WAITING);
assertEquals(0, phaser.arrive()); assertEquals(0, phaser.arrive());
awaitTermination(t); awaitTermination(t);
@ -578,7 +579,7 @@ public class PhaserTest extends JSR166TestCase {
}}); }});
await(pleaseArrive); await(pleaseArrive);
waitForThreadToEnterWaitState(t); assertThreadBlocks(t, Thread.State.WAITING);
t.interrupt(); t.interrupt();
assertEquals(0, phaser.arrive()); assertEquals(0, phaser.arrive());
awaitTermination(t); awaitTermination(t);
@ -607,7 +608,7 @@ public class PhaserTest extends JSR166TestCase {
}}); }});
await(pleaseArrive); await(pleaseArrive);
waitForThreadToEnterWaitState(t); assertThreadBlocks(t, Thread.State.WAITING);
Thread.currentThread().interrupt(); Thread.currentThread().interrupt();
assertEquals(1, phaser.arriveAndAwaitAdvance()); assertEquals(1, phaser.arriveAndAwaitAdvance());
assertTrue(Thread.interrupted()); assertTrue(Thread.interrupted());
@ -632,7 +633,7 @@ public class PhaserTest extends JSR166TestCase {
}}); }});
await(pleaseInterrupt); await(pleaseInterrupt);
waitForThreadToEnterWaitState(t); assertThreadBlocks(t, Thread.State.WAITING);
t.interrupt(); t.interrupt();
Thread.currentThread().interrupt(); Thread.currentThread().interrupt();
assertEquals(1, phaser.arriveAndAwaitAdvance()); assertEquals(1, phaser.arriveAndAwaitAdvance());
@ -807,7 +808,7 @@ public class PhaserTest extends JSR166TestCase {
assertEquals(THREADS, phaser.getArrivedParties()); assertEquals(THREADS, phaser.getArrivedParties());
assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS); assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
for (Thread thread : threads) for (Thread thread : threads)
waitForThreadToEnterWaitState(thread); assertThreadBlocks(thread, Thread.State.WAITING);
for (Thread thread : threads) for (Thread thread : threads)
assertTrue(thread.isAlive()); assertTrue(thread.isAlive());
assertState(phaser, 0, THREADS + 1, 1); assertState(phaser, 0, THREADS + 1, 1);

View File

@ -117,7 +117,7 @@ public class PriorityBlockingQueueTest extends JSR166TestCase {
} }
/** /**
* Constructor throws IAE if capacity argument nonpositive * Constructor throws IllegalArgumentException if capacity argument nonpositive
*/ */
public void testConstructor2() { public void testConstructor2() {
try { try {
@ -256,7 +256,7 @@ public class PriorityBlockingQueueTest extends JSR166TestCase {
} }
/** /**
* addAll(this) throws IAE * addAll(this) throws IllegalArgumentException
*/ */
public void testAddAllSelf() { public void testAddAllSelf() {
PriorityBlockingQueue q = populatedQueue(SIZE); PriorityBlockingQueue q = populatedQueue(SIZE);
@ -329,7 +329,7 @@ public class PriorityBlockingQueueTest extends JSR166TestCase {
/** /**
* timed offer does not time out * timed offer does not time out
*/ */
public void testTimedOffer() throws InterruptedException { public void testTimedOffer() {
final PriorityBlockingQueue q = new PriorityBlockingQueue(2); final PriorityBlockingQueue q = new PriorityBlockingQueue(2);
Thread t = newStartedThread(new CheckedRunnable() { Thread t = newStartedThread(new CheckedRunnable() {
public void realRun() { public void realRun() {
@ -360,9 +360,7 @@ public class PriorityBlockingQueueTest extends JSR166TestCase {
final CountDownLatch pleaseInterrupt = new CountDownLatch(1); final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
Thread t = newStartedThread(new CheckedRunnable() { Thread t = newStartedThread(new CheckedRunnable() {
public void realRun() throws InterruptedException { public void realRun() throws InterruptedException {
for (int i = 0; i < SIZE; ++i) { for (int i = 0; i < SIZE; i++) assertEquals(i, q.take());
assertEquals(i, q.take());
}
Thread.currentThread().interrupt(); Thread.currentThread().interrupt();
try { try {
@ -380,7 +378,7 @@ public class PriorityBlockingQueueTest extends JSR166TestCase {
}}); }});
await(pleaseInterrupt); await(pleaseInterrupt);
assertThreadStaysAlive(t); assertThreadBlocks(t, Thread.State.WAITING);
t.interrupt(); t.interrupt();
awaitTermination(t); awaitTermination(t);
} }
@ -429,24 +427,32 @@ public class PriorityBlockingQueueTest extends JSR166TestCase {
*/ */
public void testInterruptedTimedPoll() throws InterruptedException { public void testInterruptedTimedPoll() throws InterruptedException {
final BlockingQueue<Integer> q = populatedQueue(SIZE); final BlockingQueue<Integer> q = populatedQueue(SIZE);
final CountDownLatch aboutToWait = new CountDownLatch(1); final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
Thread t = newStartedThread(new CheckedRunnable() { Thread t = newStartedThread(new CheckedRunnable() {
public void realRun() throws InterruptedException { public void realRun() throws InterruptedException {
long startTime = System.nanoTime(); 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)); assertEquals(i, (int) q.poll(LONG_DELAY_MS, MILLISECONDS));
}
aboutToWait.countDown(); Thread.currentThread().interrupt();
try { try {
q.poll(LONG_DELAY_MS, MILLISECONDS); q.poll(LONG_DELAY_MS, MILLISECONDS);
shouldThrow(); shouldThrow();
} catch (InterruptedException success) { } catch (InterruptedException success) {}
assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS); 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); await(pleaseInterrupt);
waitForThreadToEnterWaitState(t); assertThreadBlocks(t, Thread.State.TIMED_WAITING);
t.interrupt(); t.interrupt();
awaitTermination(t); awaitTermination(t);
} }

View File

@ -90,7 +90,7 @@ public class PriorityQueueTest extends JSR166TestCase {
} }
/** /**
* Constructor throws IAE if capacity argument nonpositive * Constructor throws IllegalArgumentException if capacity argument nonpositive
*/ */
public void testConstructor2() { public void testConstructor2() {
try { try {

View File

@ -31,7 +31,7 @@
* http://creativecommons.org/publicdomain/zero/1.0/ * 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.Arrays;
import java.util.HashSet; import java.util.HashSet;
@ -100,14 +100,14 @@ public class RecursiveActionTest extends JSR166TestCase {
Thread.currentThread().interrupt(); Thread.currentThread().interrupt();
try { try {
a.get(5L, SECONDS); a.get(randomTimeout(), randomTimeUnit());
shouldThrow(); shouldThrow();
} catch (InterruptedException success) { } catch (InterruptedException success) {
} catch (Throwable fail) { threadUnexpectedException(fail); } } catch (Throwable fail) { threadUnexpectedException(fail); }
} }
try { try {
a.get(0L, SECONDS); a.get(randomExpiredTimeout(), randomTimeUnit());
shouldThrow(); shouldThrow();
} catch (TimeoutException success) { } catch (TimeoutException success) {
} catch (Throwable fail) { threadUnexpectedException(fail); } } catch (Throwable fail) { threadUnexpectedException(fail); }
@ -125,9 +125,7 @@ public class RecursiveActionTest extends JSR166TestCase {
assertFalse(a.cancel(true)); assertFalse(a.cancel(true));
try { try {
assertNull(a.get()); assertNull(a.get());
} catch (Throwable fail) { threadUnexpectedException(fail); } assertNull(a.get(randomTimeout(), randomTimeUnit()));
try {
assertNull(a.get(5L, SECONDS));
} catch (Throwable fail) { threadUnexpectedException(fail); } } catch (Throwable fail) { threadUnexpectedException(fail); }
} }
@ -152,7 +150,7 @@ public class RecursiveActionTest extends JSR166TestCase {
} catch (Throwable fail) { threadUnexpectedException(fail); } } catch (Throwable fail) { threadUnexpectedException(fail); }
try { try {
a.get(5L, SECONDS); a.get(randomTimeout(), randomTimeUnit());
shouldThrow(); shouldThrow();
} catch (CancellationException success) { } catch (CancellationException success) {
} catch (Throwable fail) { threadUnexpectedException(fail); } } catch (Throwable fail) { threadUnexpectedException(fail); }
@ -183,7 +181,7 @@ public class RecursiveActionTest extends JSR166TestCase {
} catch (Throwable fail) { threadUnexpectedException(fail); } } catch (Throwable fail) { threadUnexpectedException(fail); }
try { try {
a.get(5L, SECONDS); a.get(randomTimeout(), randomTimeUnit());
shouldThrow(); shouldThrow();
} catch (ExecutionException success) { } catch (ExecutionException success) {
assertSame(t.getClass(), success.getCause().getClass()); assertSame(t.getClass(), success.getCause().getClass());
@ -469,7 +467,7 @@ public class RecursiveActionTest extends JSR166TestCase {
protected void realCompute() throws Exception { protected void realCompute() throws Exception {
FibAction f = new FibAction(8); FibAction f = new FibAction(8);
assertSame(f, f.fork()); assertSame(f, f.fork());
assertNull(f.get(5L, SECONDS)); assertNull(f.get(LONG_DELAY_MS, MILLISECONDS));
assertEquals(21, f.result); assertEquals(21, f.result);
checkCompletedNormally(f); checkCompletedNormally(f);
}}; }};
@ -485,7 +483,7 @@ public class RecursiveActionTest extends JSR166TestCase {
FibAction f = new FibAction(8); FibAction f = new FibAction(8);
assertSame(f, f.fork()); assertSame(f, f.fork());
try { try {
f.get(5L, null); f.get(randomTimeout(), null);
shouldThrow(); shouldThrow();
} catch (NullPointerException success) {} } catch (NullPointerException success) {}
}}; }};
@ -604,7 +602,7 @@ public class RecursiveActionTest extends JSR166TestCase {
FailingFibAction f = new FailingFibAction(8); FailingFibAction f = new FailingFibAction(8);
assertSame(f, f.fork()); assertSame(f, f.fork());
try { try {
f.get(5L, SECONDS); f.get(LONG_DELAY_MS, MILLISECONDS);
shouldThrow(); shouldThrow();
} catch (ExecutionException success) { } catch (ExecutionException success) {
Throwable cause = success.getCause(); Throwable cause = success.getCause();
@ -696,7 +694,7 @@ public class RecursiveActionTest extends JSR166TestCase {
assertTrue(f.cancel(true)); assertTrue(f.cancel(true));
assertSame(f, f.fork()); assertSame(f, f.fork());
try { try {
f.get(5L, SECONDS); f.get(LONG_DELAY_MS, MILLISECONDS);
shouldThrow(); shouldThrow();
} catch (CancellationException success) { } catch (CancellationException success) {
checkCancelled(f); checkCancelled(f);

View File

@ -31,7 +31,7 @@
* http://creativecommons.org/publicdomain/zero/1.0/ * 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.HashSet;
import java.util.concurrent.CancellationException; import java.util.concurrent.CancellationException;
@ -96,14 +96,14 @@ public class RecursiveTaskTest extends JSR166TestCase {
Thread.currentThread().interrupt(); Thread.currentThread().interrupt();
try { try {
a.get(5L, SECONDS); a.get(randomTimeout(), randomTimeUnit());
shouldThrow(); shouldThrow();
} catch (InterruptedException success) { } catch (InterruptedException success) {
} catch (Throwable fail) { threadUnexpectedException(fail); } } catch (Throwable fail) { threadUnexpectedException(fail); }
} }
try { try {
a.get(0L, SECONDS); a.get(randomExpiredTimeout(), randomTimeUnit());
shouldThrow(); shouldThrow();
} catch (TimeoutException success) { } catch (TimeoutException success) {
} catch (Throwable fail) { threadUnexpectedException(fail); } } catch (Throwable fail) { threadUnexpectedException(fail); }
@ -121,9 +121,7 @@ public class RecursiveTaskTest extends JSR166TestCase {
assertFalse(a.cancel(true)); assertFalse(a.cancel(true));
try { try {
assertSame(expected, a.get()); assertSame(expected, a.get());
} catch (Throwable fail) { threadUnexpectedException(fail); } assertSame(expected, a.get(randomTimeout(), randomTimeUnit()));
try {
assertSame(expected, a.get(5L, SECONDS));
} catch (Throwable fail) { threadUnexpectedException(fail); } } catch (Throwable fail) { threadUnexpectedException(fail); }
} }
@ -168,7 +166,7 @@ public class RecursiveTaskTest extends JSR166TestCase {
} catch (Throwable fail) { threadUnexpectedException(fail); } } catch (Throwable fail) { threadUnexpectedException(fail); }
try { try {
a.get(5L, SECONDS); a.get(randomTimeout(), randomTimeUnit());
shouldThrow(); shouldThrow();
} catch (CancellationException success) { } catch (CancellationException success) {
} catch (Throwable fail) { threadUnexpectedException(fail); } } catch (Throwable fail) { threadUnexpectedException(fail); }
@ -199,7 +197,7 @@ public class RecursiveTaskTest extends JSR166TestCase {
} catch (Throwable fail) { threadUnexpectedException(fail); } } catch (Throwable fail) { threadUnexpectedException(fail); }
try { try {
a.get(5L, SECONDS); a.get(randomTimeout(), randomTimeUnit());
shouldThrow(); shouldThrow();
} catch (ExecutionException success) { } catch (ExecutionException success) {
assertSame(t.getClass(), success.getCause().getClass()); assertSame(t.getClass(), success.getCause().getClass());
@ -320,7 +318,7 @@ public class RecursiveTaskTest extends JSR166TestCase {
public Integer realCompute() throws Exception { public Integer realCompute() throws Exception {
FibTask f = new FibTask(8); FibTask f = new FibTask(8);
assertSame(f, f.fork()); assertSame(f, f.fork());
Integer r = f.get(5L, SECONDS); Integer r = f.get(LONG_DELAY_MS, MILLISECONDS);
assertEquals(21, (int) r); assertEquals(21, (int) r);
checkCompletedNormally(f, r); checkCompletedNormally(f, r);
return r; return r;
@ -446,7 +444,7 @@ public class RecursiveTaskTest extends JSR166TestCase {
FailingFibTask f = new FailingFibTask(8); FailingFibTask f = new FailingFibTask(8);
assertSame(f, f.fork()); assertSame(f, f.fork());
try { try {
Integer r = f.get(5L, SECONDS); Integer r = f.get(LONG_DELAY_MS, MILLISECONDS);
shouldThrow(); shouldThrow();
} catch (ExecutionException success) { } catch (ExecutionException success) {
Throwable cause = success.getCause(); Throwable cause = success.getCause();
@ -543,7 +541,7 @@ public class RecursiveTaskTest extends JSR166TestCase {
assertTrue(f.cancel(true)); assertTrue(f.cancel(true));
assertSame(f, f.fork()); assertSame(f, f.fork());
try { try {
Integer r = f.get(5L, SECONDS); Integer r = f.get(LONG_DELAY_MS, MILLISECONDS);
shouldThrow(); shouldThrow();
} catch (CancellationException success) { } catch (CancellationException success) {
checkCancelled(f); checkCancelled(f);

View File

@ -47,6 +47,7 @@ import junit.framework.AssertionFailedError;
import junit.framework.Test; import junit.framework.Test;
import junit.framework.TestSuite; import junit.framework.TestSuite;
@SuppressWarnings("WaitNotInLoop") // we implement spurious-wakeup freedom
public class ReentrantLockTest extends JSR166TestCase { public class ReentrantLockTest extends JSR166TestCase {
public static void main(String[] args) { public static void main(String[] args) {
main(suite(), args); main(suite(), args);
@ -912,7 +913,7 @@ public class ReentrantLockTest extends JSR166TestCase {
public void testAwaitUninterruptibly_fair() { testAwaitUninterruptibly(true); } public void testAwaitUninterruptibly_fair() { testAwaitUninterruptibly(true); }
public void testAwaitUninterruptibly(boolean fair) { public void testAwaitUninterruptibly(boolean fair) {
final ReentrantLock lock = new ReentrantLock(fair); final ReentrantLock lock = new ReentrantLock(fair);
final Condition c = lock.newCondition(); final Condition condition = lock.newCondition();
final CountDownLatch pleaseInterrupt = new CountDownLatch(2); final CountDownLatch pleaseInterrupt = new CountDownLatch(2);
Thread t1 = newStartedThread(new CheckedRunnable() { Thread t1 = newStartedThread(new CheckedRunnable() {
@ -921,7 +922,7 @@ public class ReentrantLockTest extends JSR166TestCase {
lock.lock(); lock.lock();
pleaseInterrupt.countDown(); pleaseInterrupt.countDown();
Thread.currentThread().interrupt(); Thread.currentThread().interrupt();
c.awaitUninterruptibly(); condition.awaitUninterruptibly();
assertTrue(Thread.interrupted()); assertTrue(Thread.interrupted());
lock.unlock(); lock.unlock();
}}); }});
@ -931,21 +932,20 @@ public class ReentrantLockTest extends JSR166TestCase {
// Interrupt during awaitUninterruptibly // Interrupt during awaitUninterruptibly
lock.lock(); lock.lock();
pleaseInterrupt.countDown(); pleaseInterrupt.countDown();
c.awaitUninterruptibly(); condition.awaitUninterruptibly();
assertTrue(Thread.interrupted()); assertTrue(Thread.interrupted());
lock.unlock(); lock.unlock();
}}); }});
await(pleaseInterrupt); await(pleaseInterrupt);
t2.interrupt();
lock.lock(); lock.lock();
lock.unlock(); lock.unlock();
t2.interrupt(); assertThreadBlocks(t1, Thread.State.WAITING);
assertThreadBlocks(t2, Thread.State.WAITING);
assertThreadStaysAlive(t1);
assertTrue(t2.isAlive());
lock.lock(); lock.lock();
c.signalAll(); condition.signalAll();
lock.unlock(); lock.unlock();
awaitTermination(t1); awaitTermination(t1);

View File

@ -48,6 +48,7 @@ import junit.framework.AssertionFailedError;
import junit.framework.Test; import junit.framework.Test;
import junit.framework.TestSuite; import junit.framework.TestSuite;
@SuppressWarnings("WaitNotInLoop") // we implement spurious-wakeup freedom
public class ReentrantReadWriteLockTest extends JSR166TestCase { public class ReentrantReadWriteLockTest extends JSR166TestCase {
public static void main(String[] args) { public static void main(String[] args) {
main(suite(), args); main(suite(), args);
@ -1036,42 +1037,41 @@ public class ReentrantReadWriteLockTest extends JSR166TestCase {
public void testAwaitUninterruptibly() { testAwaitUninterruptibly(false); } public void testAwaitUninterruptibly() { testAwaitUninterruptibly(false); }
public void testAwaitUninterruptibly_fair() { testAwaitUninterruptibly(true); } public void testAwaitUninterruptibly_fair() { testAwaitUninterruptibly(true); }
public void testAwaitUninterruptibly(boolean fair) { public void testAwaitUninterruptibly(boolean fair) {
final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair); final Lock lock = new ReentrantReadWriteLock(fair).writeLock();
final Condition c = lock.writeLock().newCondition(); final Condition condition = lock.newCondition();
final CountDownLatch pleaseInterrupt = new CountDownLatch(2); final CountDownLatch pleaseInterrupt = new CountDownLatch(2);
Thread t1 = newStartedThread(new CheckedRunnable() { Thread t1 = newStartedThread(new CheckedRunnable() {
public void realRun() { public void realRun() {
// Interrupt before awaitUninterruptibly // Interrupt before awaitUninterruptibly
lock.writeLock().lock(); lock.lock();
pleaseInterrupt.countDown(); pleaseInterrupt.countDown();
Thread.currentThread().interrupt(); Thread.currentThread().interrupt();
c.awaitUninterruptibly(); condition.awaitUninterruptibly();
assertTrue(Thread.interrupted()); assertTrue(Thread.interrupted());
lock.writeLock().unlock(); lock.unlock();
}}); }});
Thread t2 = newStartedThread(new CheckedRunnable() { Thread t2 = newStartedThread(new CheckedRunnable() {
public void realRun() { public void realRun() {
// Interrupt during awaitUninterruptibly // Interrupt during awaitUninterruptibly
lock.writeLock().lock(); lock.lock();
pleaseInterrupt.countDown(); pleaseInterrupt.countDown();
c.awaitUninterruptibly(); condition.awaitUninterruptibly();
assertTrue(Thread.interrupted()); assertTrue(Thread.interrupted());
lock.writeLock().unlock(); lock.unlock();
}}); }});
await(pleaseInterrupt); await(pleaseInterrupt);
lock.writeLock().lock();
lock.writeLock().unlock();
t2.interrupt(); t2.interrupt();
lock.lock();
lock.unlock();
assertThreadBlocks(t1, Thread.State.WAITING);
assertThreadBlocks(t2, Thread.State.WAITING);
assertThreadStaysAlive(t1); lock.lock();
assertTrue(t2.isAlive()); condition.signalAll();
lock.unlock();
lock.writeLock().lock();
c.signalAll();
lock.writeLock().unlock();
awaitTermination(t1); awaitTermination(t1);
awaitTermination(t2); awaitTermination(t2);

Some files were not shown because too many files have changed in this diff Show More