mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 14:54:52 +02:00
8211283: Miscellaneous changes imported from jsr166 CVS 2018-11
Reviewed-by: martin, chegar
This commit is contained in:
parent
5a5aa52772
commit
53d3a4f50c
14 changed files with 218 additions and 213 deletions
|
@ -37,7 +37,6 @@ package java.util;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
import jdk.internal.access.SharedSecrets;
|
import jdk.internal.access.SharedSecrets;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -2542,6 +2542,8 @@ public class ConcurrentHashMap<K,V> extends AbstractMap<K,V>
|
||||||
setTabAt(tab, i, fwd);
|
setTabAt(tab, i, fwd);
|
||||||
advance = true;
|
advance = true;
|
||||||
}
|
}
|
||||||
|
else if (f instanceof ReservationNode)
|
||||||
|
throw new IllegalStateException("Recursive update");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -564,8 +564,8 @@ public class Exchanger<V> {
|
||||||
Object item = (x == null) ? NULL_ITEM : x; // translate null args
|
Object item = (x == null) ? NULL_ITEM : x; // translate null args
|
||||||
if (((a = arena) != null ||
|
if (((a = arena) != null ||
|
||||||
(v = slotExchange(item, false, 0L)) == null) &&
|
(v = slotExchange(item, false, 0L)) == null) &&
|
||||||
((Thread.interrupted() || // disambiguates null return
|
(Thread.interrupted() || // disambiguates null return
|
||||||
(v = arenaExchange(item, false, 0L)) == null)))
|
(v = arenaExchange(item, false, 0L)) == null))
|
||||||
throw new InterruptedException();
|
throw new InterruptedException();
|
||||||
return (v == NULL_ITEM) ? null : (V)v;
|
return (v == NULL_ITEM) ? null : (V)v;
|
||||||
}
|
}
|
||||||
|
@ -620,8 +620,8 @@ public class Exchanger<V> {
|
||||||
long ns = unit.toNanos(timeout);
|
long ns = unit.toNanos(timeout);
|
||||||
if ((arena != null ||
|
if ((arena != null ||
|
||||||
(v = slotExchange(item, true, ns)) == null) &&
|
(v = slotExchange(item, true, ns)) == null) &&
|
||||||
((Thread.interrupted() ||
|
(Thread.interrupted() ||
|
||||||
(v = arenaExchange(item, true, ns)) == null)))
|
(v = arenaExchange(item, true, ns)) == null))
|
||||||
throw new InterruptedException();
|
throw new InterruptedException();
|
||||||
if (v == TIMED_OUT)
|
if (v == TIMED_OUT)
|
||||||
throw new TimeoutException();
|
throw new TimeoutException();
|
||||||
|
|
|
@ -1230,14 +1230,13 @@ public abstract class ForkJoinTask<V> implements Future<V>, Serializable {
|
||||||
/**
|
/**
|
||||||
* Immediately performs the base action of this task and returns
|
* Immediately performs the base action of this task and returns
|
||||||
* true if, upon return from this method, this task is guaranteed
|
* true if, upon return from this method, this task is guaranteed
|
||||||
* to have completed normally. This method may return false
|
* to have completed. This method may return false otherwise, to
|
||||||
* otherwise, to indicate that this task is not necessarily
|
* indicate that this task is not necessarily complete (or is not
|
||||||
* complete (or is not known to be complete), for example in
|
* known to be complete), for example in asynchronous actions that
|
||||||
* asynchronous actions that require explicit invocations of
|
* require explicit invocations of completion methods. This method
|
||||||
* completion methods. This method may also throw an (unchecked)
|
* may also throw an (unchecked) exception to indicate abnormal
|
||||||
* exception to indicate abnormal exit. This method is designed to
|
* exit. This method is designed to support extensions, and should
|
||||||
* support extensions, and should not in general be called
|
* not in general be called otherwise.
|
||||||
* otherwise.
|
|
||||||
*
|
*
|
||||||
* @return {@code true} if this task is known to have completed normally
|
* @return {@code true} if this task is known to have completed normally
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -199,10 +199,11 @@ public class LockSupport {
|
||||||
* Disables the current thread for thread scheduling purposes, for up to
|
* Disables the current thread for thread scheduling purposes, for up to
|
||||||
* the specified waiting time, unless the permit is available.
|
* the specified waiting time, unless the permit is available.
|
||||||
*
|
*
|
||||||
* <p>If the permit is available then it is consumed and the call
|
* <p>If the specified waiting time is zero or negative, the
|
||||||
* returns immediately; otherwise the current thread becomes disabled
|
* method does nothing. Otherwise, if the permit is available then
|
||||||
* for thread scheduling purposes and lies dormant until one of four
|
* it is consumed and the call returns immediately; otherwise the
|
||||||
* things happens:
|
* current thread becomes disabled for thread scheduling purposes
|
||||||
|
* and lies dormant until one of four things happens:
|
||||||
*
|
*
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>Some other thread invokes {@link #unpark unpark} with the
|
* <li>Some other thread invokes {@link #unpark unpark} with the
|
||||||
|
@ -327,10 +328,11 @@ public class LockSupport {
|
||||||
* Disables the current thread for thread scheduling purposes, for up to
|
* Disables the current thread for thread scheduling purposes, for up to
|
||||||
* the specified waiting time, unless the permit is available.
|
* the specified waiting time, unless the permit is available.
|
||||||
*
|
*
|
||||||
* <p>If the permit is available then it is consumed and the call
|
* <p>If the specified waiting time is zero or negative, the
|
||||||
* returns immediately; otherwise the current thread becomes disabled
|
* method does nothing. Otherwise, if the permit is available then
|
||||||
* for thread scheduling purposes and lies dormant until one of four
|
* it is consumed and the call returns immediately; otherwise the
|
||||||
* things happens:
|
* current thread becomes disabled for thread scheduling purposes
|
||||||
|
* and lies dormant until one of four things happens:
|
||||||
*
|
*
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>Some other thread invokes {@link #unpark unpark} with the
|
* <li>Some other thread invokes {@link #unpark unpark} with the
|
||||||
|
|
|
@ -65,22 +65,23 @@ import jdk.internal.vm.annotation.ReservedStackAccess;
|
||||||
* and timed versions of {@code tryReadLock} are also provided.
|
* and timed versions of {@code tryReadLock} are also provided.
|
||||||
*
|
*
|
||||||
* <li><b>Optimistic Reading.</b> Method {@link #tryOptimisticRead}
|
* <li><b>Optimistic Reading.</b> Method {@link #tryOptimisticRead}
|
||||||
* returns a non-zero stamp only if the lock is not currently held
|
* returns a non-zero stamp only if the lock is not currently held in
|
||||||
* in write mode. Method {@link #validate} returns true if the lock
|
* write mode. Method {@link #validate} returns true if the lock has not
|
||||||
* has not been acquired in write mode since obtaining a given
|
* been acquired in write mode since obtaining a given stamp, in which
|
||||||
* stamp. This mode can be thought of as an extremely weak version
|
* case all actions prior to the most recent write lock release
|
||||||
* of a read-lock, that can be broken by a writer at any time. The
|
* happen-before actions following the call to {@code tryOptimisticRead}.
|
||||||
* use of optimistic mode for short read-only code segments often
|
* This mode can be thought of as an extremely weak version of a
|
||||||
* reduces contention and improves throughput. However, its use is
|
* read-lock, that can be broken by a writer at any time. The use of
|
||||||
* inherently fragile. Optimistic read sections should only read
|
* optimistic read mode for short read-only code segments often reduces
|
||||||
* fields and hold them in local variables for later use after
|
* contention and improves throughput. However, its use is inherently
|
||||||
* validation. Fields read while in optimistic mode may be wildly
|
* fragile. Optimistic read sections should only read fields and hold
|
||||||
* inconsistent, so usage applies only when you are familiar enough
|
* them in local variables for later use after validation. Fields read
|
||||||
* with data representations to check consistency and/or repeatedly
|
* while in optimistic read mode may be wildly inconsistent, so usage
|
||||||
* invoke method {@code validate()}. For example, such steps are
|
* applies only when you are familiar enough with data representations to
|
||||||
* typically required when first reading an object or array
|
* check consistency and/or repeatedly invoke method {@code validate()}.
|
||||||
* reference, and then accessing one of its fields, elements or
|
* For example, such steps are typically required when first reading an
|
||||||
* methods.
|
* object or array reference, and then accessing one of its fields,
|
||||||
|
* elements or methods.
|
||||||
*
|
*
|
||||||
* </ul>
|
* </ul>
|
||||||
*
|
*
|
||||||
|
@ -88,8 +89,8 @@ import jdk.internal.vm.annotation.ReservedStackAccess;
|
||||||
* conversions across the three modes. For example, method {@link
|
* conversions across the three modes. For example, method {@link
|
||||||
* #tryConvertToWriteLock} attempts to "upgrade" a mode, returning
|
* #tryConvertToWriteLock} attempts to "upgrade" a mode, returning
|
||||||
* a valid write stamp if (1) already in writing mode (2) in reading
|
* a valid write stamp if (1) already in writing mode (2) in reading
|
||||||
* mode and there are no other readers or (3) in optimistic mode and
|
* mode and there are no other readers or (3) in optimistic read mode
|
||||||
* the lock is available. The forms of these methods are designed to
|
* and the lock is available. The forms of these methods are designed to
|
||||||
* help reduce some of the code bloat that otherwise occurs in
|
* help reduce some of the code bloat that otherwise occurs in
|
||||||
* retry-based designs.
|
* retry-based designs.
|
||||||
*
|
*
|
||||||
|
@ -129,6 +130,19 @@ import jdk.internal.vm.annotation.ReservedStackAccess;
|
||||||
* #asReadWriteLock()} in applications requiring only the associated
|
* #asReadWriteLock()} in applications requiring only the associated
|
||||||
* set of functionality.
|
* set of functionality.
|
||||||
*
|
*
|
||||||
|
* <p><b>Memory Synchronization.</b> Methods with the effect of
|
||||||
|
* successfully locking in any mode have the same memory
|
||||||
|
* synchronization effects as a <em>Lock</em> action described in
|
||||||
|
* <a href="https://docs.oracle.com/javase/specs/jls/se8/html/jls-17.html#jls-17.4">
|
||||||
|
* Chapter 17 of <cite>The Java™ Language Specification</cite></a>.
|
||||||
|
* Methods successfully unlocking in write mode have the same memory
|
||||||
|
* synchronization effects as an <em>Unlock</em> action. In optimistic
|
||||||
|
* read usages, actions prior to the most recent write mode unlock action
|
||||||
|
* are guaranteed to happen-before those following a tryOptimisticRead
|
||||||
|
* only if a later validate returns true; otherwise there is no guarantee
|
||||||
|
* that the reads between tryOptimisticRead and validate obtain a
|
||||||
|
* consistent snapshot.
|
||||||
|
*
|
||||||
* <p><b>Sample Usage.</b> The following illustrates some usage idioms
|
* <p><b>Sample Usage.</b> The following illustrates some usage idioms
|
||||||
* in a class that maintains simple two-dimensional points. The sample
|
* in a class that maintains simple two-dimensional points. The sample
|
||||||
* code illustrates some try/catch conventions even though they are
|
* code illustrates some try/catch conventions even though they are
|
||||||
|
|
|
@ -93,14 +93,14 @@ public class LongAdderDemo {
|
||||||
report(nthreads, incs, timeTasks(phaser), a.sum());
|
report(nthreads, incs, timeTasks(phaser), a.sum());
|
||||||
}
|
}
|
||||||
|
|
||||||
static void report(int nthreads, int incs, long time, long sum) {
|
static void report(int nthreads, int incs, long elapsedNanos, long sum) {
|
||||||
long total = (long)nthreads * incs;
|
long total = (long)nthreads * incs;
|
||||||
if (sum != total)
|
if (sum != total)
|
||||||
throw new Error(sum + " != " + total);
|
throw new Error(sum + " != " + total);
|
||||||
double secs = (double)time / (1000L * 1000 * 1000);
|
double elapsedSecs = (double)elapsedNanos / (1000L * 1000 * 1000);
|
||||||
long rate = total * (1000L) / time;
|
long rate = total * 1000L / elapsedNanos;
|
||||||
System.out.printf("threads:%3d Time: %7.3fsec Incs per microsec: %4d\n",
|
System.out.printf("threads:%3d Time: %7.3fsec Incs per microsec: %4d\n",
|
||||||
nthreads, secs, rate);
|
nthreads, elapsedSecs, rate);
|
||||||
}
|
}
|
||||||
|
|
||||||
static long timeTasks(Phaser phaser) {
|
static long timeTasks(Phaser phaser) {
|
||||||
|
|
|
@ -953,17 +953,19 @@ public class CompletableFutureTest extends JSR166TestCase {
|
||||||
for (boolean createIncomplete : new boolean[] { true, false })
|
for (boolean createIncomplete : new boolean[] { true, false })
|
||||||
for (Integer v1 : new Integer[] { 1, null })
|
for (Integer v1 : new Integer[] { 1, null })
|
||||||
{
|
{
|
||||||
|
final AtomicInteger ran = new AtomicInteger(0);
|
||||||
final CompletableFuture<Integer> f = new CompletableFuture<>();
|
final CompletableFuture<Integer> f = new CompletableFuture<>();
|
||||||
if (!createIncomplete) assertTrue(f.complete(v1));
|
if (!createIncomplete) assertTrue(f.complete(v1));
|
||||||
final CompletableFuture<Integer> g = m.exceptionally
|
final CompletableFuture<Integer> g = m.exceptionally
|
||||||
(f, (Throwable t) -> {
|
(f, (Throwable t) -> {
|
||||||
threadFail("should not be called");
|
ran.getAndIncrement();
|
||||||
return null; // unreached
|
throw new AssertionError("should not be called");
|
||||||
});
|
});
|
||||||
if (createIncomplete) assertTrue(f.complete(v1));
|
if (createIncomplete) assertTrue(f.complete(v1));
|
||||||
|
|
||||||
checkCompletedNormally(g, v1);
|
checkCompletedNormally(g, v1);
|
||||||
checkCompletedNormally(f, v1);
|
checkCompletedNormally(f, v1);
|
||||||
|
assertEquals(0, ran.get());
|
||||||
}}
|
}}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -975,21 +977,21 @@ public class CompletableFutureTest extends JSR166TestCase {
|
||||||
for (boolean createIncomplete : new boolean[] { true, false })
|
for (boolean createIncomplete : new boolean[] { true, false })
|
||||||
for (Integer v1 : new Integer[] { 1, null })
|
for (Integer v1 : new Integer[] { 1, null })
|
||||||
{
|
{
|
||||||
final AtomicInteger a = new AtomicInteger(0);
|
final AtomicInteger ran = new AtomicInteger(0);
|
||||||
final CFException ex = new CFException();
|
final CFException ex = new CFException();
|
||||||
final CompletableFuture<Integer> f = new CompletableFuture<>();
|
final CompletableFuture<Integer> f = new CompletableFuture<>();
|
||||||
if (!createIncomplete) f.completeExceptionally(ex);
|
if (!createIncomplete) f.completeExceptionally(ex);
|
||||||
final CompletableFuture<Integer> g = m.exceptionally
|
final CompletableFuture<Integer> g = m.exceptionally
|
||||||
(f, (Throwable t) -> {
|
(f, (Throwable t) -> {
|
||||||
m.checkExecutionMode();
|
m.checkExecutionMode();
|
||||||
threadAssertSame(t, ex);
|
assertSame(t, ex);
|
||||||
a.getAndIncrement();
|
ran.getAndIncrement();
|
||||||
return v1;
|
return v1;
|
||||||
});
|
});
|
||||||
if (createIncomplete) f.completeExceptionally(ex);
|
if (createIncomplete) f.completeExceptionally(ex);
|
||||||
|
|
||||||
checkCompletedNormally(g, v1);
|
checkCompletedNormally(g, v1);
|
||||||
assertEquals(1, a.get());
|
assertEquals(1, ran.get());
|
||||||
}}
|
}}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1000,7 +1002,7 @@ public class CompletableFutureTest extends JSR166TestCase {
|
||||||
for (ExecutionMode m : ExecutionMode.values())
|
for (ExecutionMode m : ExecutionMode.values())
|
||||||
for (boolean createIncomplete : new boolean[] { true, false })
|
for (boolean createIncomplete : new boolean[] { true, false })
|
||||||
{
|
{
|
||||||
final AtomicInteger a = new AtomicInteger(0);
|
final AtomicInteger ran = new AtomicInteger(0);
|
||||||
final CFException ex1 = new CFException();
|
final CFException ex1 = new CFException();
|
||||||
final CFException ex2 = new CFException();
|
final CFException ex2 = new CFException();
|
||||||
final CompletableFuture<Integer> f = new CompletableFuture<>();
|
final CompletableFuture<Integer> f = new CompletableFuture<>();
|
||||||
|
@ -1008,15 +1010,15 @@ public class CompletableFutureTest extends JSR166TestCase {
|
||||||
final CompletableFuture<Integer> g = m.exceptionally
|
final CompletableFuture<Integer> g = m.exceptionally
|
||||||
(f, (Throwable t) -> {
|
(f, (Throwable t) -> {
|
||||||
m.checkExecutionMode();
|
m.checkExecutionMode();
|
||||||
threadAssertSame(t, ex1);
|
assertSame(t, ex1);
|
||||||
a.getAndIncrement();
|
ran.getAndIncrement();
|
||||||
throw ex2;
|
throw ex2;
|
||||||
});
|
});
|
||||||
if (createIncomplete) f.completeExceptionally(ex1);
|
if (createIncomplete) f.completeExceptionally(ex1);
|
||||||
|
|
||||||
checkCompletedWithWrappedException(g, ex2);
|
checkCompletedWithWrappedException(g, ex2);
|
||||||
checkCompletedExceptionally(f, ex1);
|
checkCompletedExceptionally(f, ex1);
|
||||||
assertEquals(1, a.get());
|
assertEquals(1, ran.get());
|
||||||
}}
|
}}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1028,22 +1030,22 @@ public class CompletableFutureTest extends JSR166TestCase {
|
||||||
for (boolean createIncomplete : new boolean[] { true, false })
|
for (boolean createIncomplete : new boolean[] { true, false })
|
||||||
for (Integer v1 : new Integer[] { 1, null })
|
for (Integer v1 : new Integer[] { 1, null })
|
||||||
{
|
{
|
||||||
final AtomicInteger a = new AtomicInteger(0);
|
final AtomicInteger ran = new AtomicInteger(0);
|
||||||
final CompletableFuture<Integer> f = new CompletableFuture<>();
|
final CompletableFuture<Integer> f = new CompletableFuture<>();
|
||||||
if (!createIncomplete) assertTrue(f.complete(v1));
|
if (!createIncomplete) assertTrue(f.complete(v1));
|
||||||
final CompletableFuture<Integer> g = m.whenComplete
|
final CompletableFuture<Integer> g = m.whenComplete
|
||||||
(f,
|
(f,
|
||||||
(Integer result, Throwable t) -> {
|
(Integer result, Throwable t) -> {
|
||||||
m.checkExecutionMode();
|
m.checkExecutionMode();
|
||||||
threadAssertSame(result, v1);
|
assertSame(result, v1);
|
||||||
threadAssertNull(t);
|
assertNull(t);
|
||||||
a.getAndIncrement();
|
ran.getAndIncrement();
|
||||||
});
|
});
|
||||||
if (createIncomplete) assertTrue(f.complete(v1));
|
if (createIncomplete) assertTrue(f.complete(v1));
|
||||||
|
|
||||||
checkCompletedNormally(g, v1);
|
checkCompletedNormally(g, v1);
|
||||||
checkCompletedNormally(f, v1);
|
checkCompletedNormally(f, v1);
|
||||||
assertEquals(1, a.get());
|
assertEquals(1, ran.get());
|
||||||
}}
|
}}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1054,7 +1056,7 @@ public class CompletableFutureTest extends JSR166TestCase {
|
||||||
for (ExecutionMode m : ExecutionMode.values())
|
for (ExecutionMode m : ExecutionMode.values())
|
||||||
for (boolean createIncomplete : new boolean[] { true, false })
|
for (boolean createIncomplete : new boolean[] { true, false })
|
||||||
{
|
{
|
||||||
final AtomicInteger a = new AtomicInteger(0);
|
final AtomicInteger ran = new AtomicInteger(0);
|
||||||
final CFException ex = new CFException();
|
final CFException ex = new CFException();
|
||||||
final CompletableFuture<Integer> f = new CompletableFuture<>();
|
final CompletableFuture<Integer> f = new CompletableFuture<>();
|
||||||
if (!createIncomplete) f.completeExceptionally(ex);
|
if (!createIncomplete) f.completeExceptionally(ex);
|
||||||
|
@ -1062,15 +1064,15 @@ public class CompletableFutureTest extends JSR166TestCase {
|
||||||
(f,
|
(f,
|
||||||
(Integer result, Throwable t) -> {
|
(Integer result, Throwable t) -> {
|
||||||
m.checkExecutionMode();
|
m.checkExecutionMode();
|
||||||
threadAssertNull(result);
|
assertNull(result);
|
||||||
threadAssertSame(t, ex);
|
assertSame(t, ex);
|
||||||
a.getAndIncrement();
|
ran.getAndIncrement();
|
||||||
});
|
});
|
||||||
if (createIncomplete) f.completeExceptionally(ex);
|
if (createIncomplete) f.completeExceptionally(ex);
|
||||||
|
|
||||||
checkCompletedWithWrappedException(g, ex);
|
checkCompletedWithWrappedException(g, ex);
|
||||||
checkCompletedExceptionally(f, ex);
|
checkCompletedExceptionally(f, ex);
|
||||||
assertEquals(1, a.get());
|
assertEquals(1, ran.get());
|
||||||
}}
|
}}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1082,22 +1084,22 @@ public class CompletableFutureTest extends JSR166TestCase {
|
||||||
for (boolean mayInterruptIfRunning : new boolean[] { true, false })
|
for (boolean mayInterruptIfRunning : new boolean[] { true, false })
|
||||||
for (boolean createIncomplete : new boolean[] { true, false })
|
for (boolean createIncomplete : new boolean[] { true, false })
|
||||||
{
|
{
|
||||||
final AtomicInteger a = new AtomicInteger(0);
|
final AtomicInteger ran = new AtomicInteger(0);
|
||||||
final CompletableFuture<Integer> f = new CompletableFuture<>();
|
final CompletableFuture<Integer> f = new CompletableFuture<>();
|
||||||
if (!createIncomplete) assertTrue(f.cancel(mayInterruptIfRunning));
|
if (!createIncomplete) assertTrue(f.cancel(mayInterruptIfRunning));
|
||||||
final CompletableFuture<Integer> g = m.whenComplete
|
final CompletableFuture<Integer> g = m.whenComplete
|
||||||
(f,
|
(f,
|
||||||
(Integer result, Throwable t) -> {
|
(Integer result, Throwable t) -> {
|
||||||
m.checkExecutionMode();
|
m.checkExecutionMode();
|
||||||
threadAssertNull(result);
|
assertNull(result);
|
||||||
threadAssertTrue(t instanceof CancellationException);
|
assertTrue(t instanceof CancellationException);
|
||||||
a.getAndIncrement();
|
ran.getAndIncrement();
|
||||||
});
|
});
|
||||||
if (createIncomplete) assertTrue(f.cancel(mayInterruptIfRunning));
|
if (createIncomplete) assertTrue(f.cancel(mayInterruptIfRunning));
|
||||||
|
|
||||||
checkCompletedWithWrappedCancellationException(g);
|
checkCompletedWithWrappedCancellationException(g);
|
||||||
checkCancelled(f);
|
checkCancelled(f);
|
||||||
assertEquals(1, a.get());
|
assertEquals(1, ran.get());
|
||||||
}}
|
}}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1109,7 +1111,7 @@ public class CompletableFutureTest extends JSR166TestCase {
|
||||||
for (ExecutionMode m : ExecutionMode.values())
|
for (ExecutionMode m : ExecutionMode.values())
|
||||||
for (Integer v1 : new Integer[] { 1, null })
|
for (Integer v1 : new Integer[] { 1, null })
|
||||||
{
|
{
|
||||||
final AtomicInteger a = new AtomicInteger(0);
|
final AtomicInteger ran = new AtomicInteger(0);
|
||||||
final CFException ex = new CFException();
|
final CFException ex = new CFException();
|
||||||
final CompletableFuture<Integer> f = new CompletableFuture<>();
|
final CompletableFuture<Integer> f = new CompletableFuture<>();
|
||||||
if (!createIncomplete) assertTrue(f.complete(v1));
|
if (!createIncomplete) assertTrue(f.complete(v1));
|
||||||
|
@ -1117,16 +1119,16 @@ public class CompletableFutureTest extends JSR166TestCase {
|
||||||
(f,
|
(f,
|
||||||
(Integer result, Throwable t) -> {
|
(Integer result, Throwable t) -> {
|
||||||
m.checkExecutionMode();
|
m.checkExecutionMode();
|
||||||
threadAssertSame(result, v1);
|
assertSame(result, v1);
|
||||||
threadAssertNull(t);
|
assertNull(t);
|
||||||
a.getAndIncrement();
|
ran.getAndIncrement();
|
||||||
throw ex;
|
throw ex;
|
||||||
});
|
});
|
||||||
if (createIncomplete) assertTrue(f.complete(v1));
|
if (createIncomplete) assertTrue(f.complete(v1));
|
||||||
|
|
||||||
checkCompletedWithWrappedException(g, ex);
|
checkCompletedWithWrappedException(g, ex);
|
||||||
checkCompletedNormally(f, v1);
|
checkCompletedNormally(f, v1);
|
||||||
assertEquals(1, a.get());
|
assertEquals(1, ran.get());
|
||||||
}}
|
}}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1138,7 +1140,7 @@ public class CompletableFutureTest extends JSR166TestCase {
|
||||||
for (boolean createIncomplete : new boolean[] { true, false })
|
for (boolean createIncomplete : new boolean[] { true, false })
|
||||||
for (ExecutionMode m : ExecutionMode.values())
|
for (ExecutionMode m : ExecutionMode.values())
|
||||||
{
|
{
|
||||||
final AtomicInteger a = new AtomicInteger(0);
|
final AtomicInteger ran = new AtomicInteger(0);
|
||||||
final CFException ex1 = new CFException();
|
final CFException ex1 = new CFException();
|
||||||
final CFException ex2 = new CFException();
|
final CFException ex2 = new CFException();
|
||||||
final CompletableFuture<Integer> f = new CompletableFuture<>();
|
final CompletableFuture<Integer> f = new CompletableFuture<>();
|
||||||
|
@ -1148,9 +1150,9 @@ public class CompletableFutureTest extends JSR166TestCase {
|
||||||
(f,
|
(f,
|
||||||
(Integer result, Throwable t) -> {
|
(Integer result, Throwable t) -> {
|
||||||
m.checkExecutionMode();
|
m.checkExecutionMode();
|
||||||
threadAssertSame(t, ex1);
|
assertSame(t, ex1);
|
||||||
threadAssertNull(result);
|
assertNull(result);
|
||||||
a.getAndIncrement();
|
ran.getAndIncrement();
|
||||||
throw ex2;
|
throw ex2;
|
||||||
});
|
});
|
||||||
if (createIncomplete) f.completeExceptionally(ex1);
|
if (createIncomplete) f.completeExceptionally(ex1);
|
||||||
|
@ -1161,7 +1163,7 @@ public class CompletableFutureTest extends JSR166TestCase {
|
||||||
assertEquals(1, ex1.getSuppressed().length);
|
assertEquals(1, ex1.getSuppressed().length);
|
||||||
assertSame(ex2, ex1.getSuppressed()[0]);
|
assertSame(ex2, ex1.getSuppressed()[0]);
|
||||||
}
|
}
|
||||||
assertEquals(1, a.get());
|
assertEquals(1, ran.get());
|
||||||
}}
|
}}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1174,22 +1176,22 @@ public class CompletableFutureTest extends JSR166TestCase {
|
||||||
for (Integer v1 : new Integer[] { 1, null })
|
for (Integer v1 : new Integer[] { 1, null })
|
||||||
{
|
{
|
||||||
final CompletableFuture<Integer> f = new CompletableFuture<>();
|
final CompletableFuture<Integer> f = new CompletableFuture<>();
|
||||||
final AtomicInteger a = new AtomicInteger(0);
|
final AtomicInteger ran = new AtomicInteger(0);
|
||||||
if (!createIncomplete) assertTrue(f.complete(v1));
|
if (!createIncomplete) assertTrue(f.complete(v1));
|
||||||
final CompletableFuture<Integer> g = m.handle
|
final CompletableFuture<Integer> g = m.handle
|
||||||
(f,
|
(f,
|
||||||
(Integer result, Throwable t) -> {
|
(Integer result, Throwable t) -> {
|
||||||
m.checkExecutionMode();
|
m.checkExecutionMode();
|
||||||
threadAssertSame(result, v1);
|
assertSame(result, v1);
|
||||||
threadAssertNull(t);
|
assertNull(t);
|
||||||
a.getAndIncrement();
|
ran.getAndIncrement();
|
||||||
return inc(v1);
|
return inc(v1);
|
||||||
});
|
});
|
||||||
if (createIncomplete) assertTrue(f.complete(v1));
|
if (createIncomplete) assertTrue(f.complete(v1));
|
||||||
|
|
||||||
checkCompletedNormally(g, inc(v1));
|
checkCompletedNormally(g, inc(v1));
|
||||||
checkCompletedNormally(f, v1);
|
checkCompletedNormally(f, v1);
|
||||||
assertEquals(1, a.get());
|
assertEquals(1, ran.get());
|
||||||
}}
|
}}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1202,23 +1204,23 @@ public class CompletableFutureTest extends JSR166TestCase {
|
||||||
for (Integer v1 : new Integer[] { 1, null })
|
for (Integer v1 : new Integer[] { 1, null })
|
||||||
{
|
{
|
||||||
final CompletableFuture<Integer> f = new CompletableFuture<>();
|
final CompletableFuture<Integer> f = new CompletableFuture<>();
|
||||||
final AtomicInteger a = new AtomicInteger(0);
|
final AtomicInteger ran = new AtomicInteger(0);
|
||||||
final CFException ex = new CFException();
|
final CFException ex = new CFException();
|
||||||
if (!createIncomplete) f.completeExceptionally(ex);
|
if (!createIncomplete) f.completeExceptionally(ex);
|
||||||
final CompletableFuture<Integer> g = m.handle
|
final CompletableFuture<Integer> g = m.handle
|
||||||
(f,
|
(f,
|
||||||
(Integer result, Throwable t) -> {
|
(Integer result, Throwable t) -> {
|
||||||
m.checkExecutionMode();
|
m.checkExecutionMode();
|
||||||
threadAssertNull(result);
|
assertNull(result);
|
||||||
threadAssertSame(t, ex);
|
assertSame(t, ex);
|
||||||
a.getAndIncrement();
|
ran.getAndIncrement();
|
||||||
return v1;
|
return v1;
|
||||||
});
|
});
|
||||||
if (createIncomplete) f.completeExceptionally(ex);
|
if (createIncomplete) f.completeExceptionally(ex);
|
||||||
|
|
||||||
checkCompletedNormally(g, v1);
|
checkCompletedNormally(g, v1);
|
||||||
checkCompletedExceptionally(f, ex);
|
checkCompletedExceptionally(f, ex);
|
||||||
assertEquals(1, a.get());
|
assertEquals(1, ran.get());
|
||||||
}}
|
}}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1232,22 +1234,22 @@ public class CompletableFutureTest extends JSR166TestCase {
|
||||||
for (Integer v1 : new Integer[] { 1, null })
|
for (Integer v1 : new Integer[] { 1, null })
|
||||||
{
|
{
|
||||||
final CompletableFuture<Integer> f = new CompletableFuture<>();
|
final CompletableFuture<Integer> f = new CompletableFuture<>();
|
||||||
final AtomicInteger a = new AtomicInteger(0);
|
final AtomicInteger ran = new AtomicInteger(0);
|
||||||
if (!createIncomplete) assertTrue(f.cancel(mayInterruptIfRunning));
|
if (!createIncomplete) assertTrue(f.cancel(mayInterruptIfRunning));
|
||||||
final CompletableFuture<Integer> g = m.handle
|
final CompletableFuture<Integer> g = m.handle
|
||||||
(f,
|
(f,
|
||||||
(Integer result, Throwable t) -> {
|
(Integer result, Throwable t) -> {
|
||||||
m.checkExecutionMode();
|
m.checkExecutionMode();
|
||||||
threadAssertNull(result);
|
assertNull(result);
|
||||||
threadAssertTrue(t instanceof CancellationException);
|
assertTrue(t instanceof CancellationException);
|
||||||
a.getAndIncrement();
|
ran.getAndIncrement();
|
||||||
return v1;
|
return v1;
|
||||||
});
|
});
|
||||||
if (createIncomplete) assertTrue(f.cancel(mayInterruptIfRunning));
|
if (createIncomplete) assertTrue(f.cancel(mayInterruptIfRunning));
|
||||||
|
|
||||||
checkCompletedNormally(g, v1);
|
checkCompletedNormally(g, v1);
|
||||||
checkCancelled(f);
|
checkCancelled(f);
|
||||||
assertEquals(1, a.get());
|
assertEquals(1, ran.get());
|
||||||
}}
|
}}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1260,23 +1262,23 @@ public class CompletableFutureTest extends JSR166TestCase {
|
||||||
for (Integer v1 : new Integer[] { 1, null })
|
for (Integer v1 : new Integer[] { 1, null })
|
||||||
{
|
{
|
||||||
final CompletableFuture<Integer> f = new CompletableFuture<>();
|
final CompletableFuture<Integer> f = new CompletableFuture<>();
|
||||||
final AtomicInteger a = new AtomicInteger(0);
|
final AtomicInteger ran = new AtomicInteger(0);
|
||||||
final CFException ex = new CFException();
|
final CFException ex = new CFException();
|
||||||
if (!createIncomplete) assertTrue(f.complete(v1));
|
if (!createIncomplete) assertTrue(f.complete(v1));
|
||||||
final CompletableFuture<Integer> g = m.handle
|
final CompletableFuture<Integer> g = m.handle
|
||||||
(f,
|
(f,
|
||||||
(Integer result, Throwable t) -> {
|
(Integer result, Throwable t) -> {
|
||||||
m.checkExecutionMode();
|
m.checkExecutionMode();
|
||||||
threadAssertSame(result, v1);
|
assertSame(result, v1);
|
||||||
threadAssertNull(t);
|
assertNull(t);
|
||||||
a.getAndIncrement();
|
ran.getAndIncrement();
|
||||||
throw ex;
|
throw ex;
|
||||||
});
|
});
|
||||||
if (createIncomplete) assertTrue(f.complete(v1));
|
if (createIncomplete) assertTrue(f.complete(v1));
|
||||||
|
|
||||||
checkCompletedWithWrappedException(g, ex);
|
checkCompletedWithWrappedException(g, ex);
|
||||||
checkCompletedNormally(f, v1);
|
checkCompletedNormally(f, v1);
|
||||||
assertEquals(1, a.get());
|
assertEquals(1, ran.get());
|
||||||
}}
|
}}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1288,7 +1290,7 @@ public class CompletableFutureTest extends JSR166TestCase {
|
||||||
for (boolean createIncomplete : new boolean[] { true, false })
|
for (boolean createIncomplete : new boolean[] { true, false })
|
||||||
for (ExecutionMode m : ExecutionMode.values())
|
for (ExecutionMode m : ExecutionMode.values())
|
||||||
{
|
{
|
||||||
final AtomicInteger a = new AtomicInteger(0);
|
final AtomicInteger ran = new AtomicInteger(0);
|
||||||
final CFException ex1 = new CFException();
|
final CFException ex1 = new CFException();
|
||||||
final CFException ex2 = new CFException();
|
final CFException ex2 = new CFException();
|
||||||
final CompletableFuture<Integer> f = new CompletableFuture<>();
|
final CompletableFuture<Integer> f = new CompletableFuture<>();
|
||||||
|
@ -1298,16 +1300,16 @@ public class CompletableFutureTest extends JSR166TestCase {
|
||||||
(f,
|
(f,
|
||||||
(Integer result, Throwable t) -> {
|
(Integer result, Throwable t) -> {
|
||||||
m.checkExecutionMode();
|
m.checkExecutionMode();
|
||||||
threadAssertNull(result);
|
assertNull(result);
|
||||||
threadAssertSame(ex1, t);
|
assertSame(ex1, t);
|
||||||
a.getAndIncrement();
|
ran.getAndIncrement();
|
||||||
throw ex2;
|
throw ex2;
|
||||||
});
|
});
|
||||||
if (createIncomplete) f.completeExceptionally(ex1);
|
if (createIncomplete) f.completeExceptionally(ex1);
|
||||||
|
|
||||||
checkCompletedWithWrappedException(g, ex2);
|
checkCompletedWithWrappedException(g, ex2);
|
||||||
checkCompletedExceptionally(f, ex1);
|
checkCompletedExceptionally(f, ex1);
|
||||||
assertEquals(1, a.get());
|
assertEquals(1, ran.get());
|
||||||
}}
|
}}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -3143,30 +3145,30 @@ public class CompletableFutureTest extends JSR166TestCase {
|
||||||
case 0:
|
case 0:
|
||||||
assertTrue(f.complete(v1));
|
assertTrue(f.complete(v1));
|
||||||
assertTrue(g.completeExceptionally(ex));
|
assertTrue(g.completeExceptionally(ex));
|
||||||
h = m.thenCompose(f, (x -> g));
|
h = m.thenCompose(f, x -> g);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
assertTrue(f.complete(v1));
|
assertTrue(f.complete(v1));
|
||||||
h = m.thenCompose(f, (x -> g));
|
h = m.thenCompose(f, x -> g);
|
||||||
assertTrue(g.completeExceptionally(ex));
|
assertTrue(g.completeExceptionally(ex));
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
assertTrue(g.completeExceptionally(ex));
|
assertTrue(g.completeExceptionally(ex));
|
||||||
assertTrue(f.complete(v1));
|
assertTrue(f.complete(v1));
|
||||||
h = m.thenCompose(f, (x -> g));
|
h = m.thenCompose(f, x -> g);
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
assertTrue(g.completeExceptionally(ex));
|
assertTrue(g.completeExceptionally(ex));
|
||||||
h = m.thenCompose(f, (x -> g));
|
h = m.thenCompose(f, x -> g);
|
||||||
assertTrue(f.complete(v1));
|
assertTrue(f.complete(v1));
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
h = m.thenCompose(f, (x -> g));
|
h = m.thenCompose(f, x -> g);
|
||||||
assertTrue(f.complete(v1));
|
assertTrue(f.complete(v1));
|
||||||
assertTrue(g.completeExceptionally(ex));
|
assertTrue(g.completeExceptionally(ex));
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
h = m.thenCompose(f, (x -> g));
|
h = m.thenCompose(f, x -> g);
|
||||||
assertTrue(f.complete(v1));
|
assertTrue(f.complete(v1));
|
||||||
assertTrue(g.completeExceptionally(ex));
|
assertTrue(g.completeExceptionally(ex));
|
||||||
break;
|
break;
|
||||||
|
@ -3258,30 +3260,30 @@ public class CompletableFutureTest extends JSR166TestCase {
|
||||||
case 0:
|
case 0:
|
||||||
assertTrue(f.completeExceptionally(ex0));
|
assertTrue(f.completeExceptionally(ex0));
|
||||||
assertTrue(g.completeExceptionally(ex));
|
assertTrue(g.completeExceptionally(ex));
|
||||||
h = m.exceptionallyCompose(f, (x -> g));
|
h = m.exceptionallyCompose(f, x -> g);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
assertTrue(f.completeExceptionally(ex0));
|
assertTrue(f.completeExceptionally(ex0));
|
||||||
h = m.exceptionallyCompose(f, (x -> g));
|
h = m.exceptionallyCompose(f, x -> g);
|
||||||
assertTrue(g.completeExceptionally(ex));
|
assertTrue(g.completeExceptionally(ex));
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
assertTrue(g.completeExceptionally(ex));
|
assertTrue(g.completeExceptionally(ex));
|
||||||
assertTrue(f.completeExceptionally(ex0));
|
assertTrue(f.completeExceptionally(ex0));
|
||||||
h = m.exceptionallyCompose(f, (x -> g));
|
h = m.exceptionallyCompose(f, x -> g);
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
assertTrue(g.completeExceptionally(ex));
|
assertTrue(g.completeExceptionally(ex));
|
||||||
h = m.exceptionallyCompose(f, (x -> g));
|
h = m.exceptionallyCompose(f, x -> g);
|
||||||
assertTrue(f.completeExceptionally(ex0));
|
assertTrue(f.completeExceptionally(ex0));
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
h = m.exceptionallyCompose(f, (x -> g));
|
h = m.exceptionallyCompose(f, x -> g);
|
||||||
assertTrue(f.completeExceptionally(ex0));
|
assertTrue(f.completeExceptionally(ex0));
|
||||||
assertTrue(g.completeExceptionally(ex));
|
assertTrue(g.completeExceptionally(ex));
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
h = m.exceptionallyCompose(f, (x -> g));
|
h = m.exceptionallyCompose(f, x -> g);
|
||||||
assertTrue(f.completeExceptionally(ex0));
|
assertTrue(f.completeExceptionally(ex0));
|
||||||
assertTrue(g.completeExceptionally(ex));
|
assertTrue(g.completeExceptionally(ex));
|
||||||
break;
|
break;
|
||||||
|
@ -3672,12 +3674,6 @@ public class CompletableFutureTest extends JSR166TestCase {
|
||||||
final CompletableFuture<Integer> complete = CompletableFuture.completedFuture(v);
|
final CompletableFuture<Integer> complete = CompletableFuture.completedFuture(v);
|
||||||
final CompletableFuture<Integer> incomplete = new CompletableFuture<>();
|
final CompletableFuture<Integer> incomplete = new CompletableFuture<>();
|
||||||
|
|
||||||
List<CompletableFuture<?>> futures = new ArrayList<>();
|
|
||||||
|
|
||||||
List<CompletableFuture<Integer>> srcs = new ArrayList<>();
|
|
||||||
srcs.add(complete);
|
|
||||||
srcs.add(incomplete);
|
|
||||||
|
|
||||||
List<CompletableFuture<?>> fs = new ArrayList<>();
|
List<CompletableFuture<?>> fs = new ArrayList<>();
|
||||||
fs.add(incomplete.thenRunAsync(() -> {}, e));
|
fs.add(incomplete.thenRunAsync(() -> {}, e));
|
||||||
fs.add(incomplete.thenAcceptAsync(z -> {}, e));
|
fs.add(incomplete.thenAcceptAsync(z -> {}, e));
|
||||||
|
@ -4862,18 +4858,21 @@ public class CompletableFutureTest extends JSR166TestCase {
|
||||||
for (boolean createIncomplete : new boolean[] { true, false })
|
for (boolean createIncomplete : new boolean[] { true, false })
|
||||||
for (Integer v1 : new Integer[] { 1, null })
|
for (Integer v1 : new Integer[] { 1, null })
|
||||||
{
|
{
|
||||||
|
final AtomicInteger ran = new AtomicInteger(0);
|
||||||
final CompletableFuture<Integer> f = new CompletableFuture<>();
|
final CompletableFuture<Integer> f = new CompletableFuture<>();
|
||||||
final DelegatedCompletionStage<Integer> d =
|
final DelegatedCompletionStage<Integer> d =
|
||||||
new DelegatedCompletionStage<Integer>(f);
|
new DelegatedCompletionStage<Integer>(f);
|
||||||
if (!createIncomplete) assertTrue(f.complete(v1));
|
if (!createIncomplete) assertTrue(f.complete(v1));
|
||||||
final CompletionStage<Integer> g = d.exceptionallyAsync
|
final CompletionStage<Integer> g = d.exceptionallyAsync
|
||||||
((Throwable t) -> {
|
((Throwable t) -> {
|
||||||
threadFail("should not be called");
|
ran.getAndIncrement();
|
||||||
return null; // unreached
|
throw new AssertionError("should not be called");
|
||||||
});
|
});
|
||||||
if (createIncomplete) assertTrue(f.complete(v1));
|
if (createIncomplete) assertTrue(f.complete(v1));
|
||||||
|
|
||||||
checkCompletedNormally(g.toCompletableFuture(), v1);
|
checkCompletedNormally(g.toCompletableFuture(), v1);
|
||||||
|
checkCompletedNormally(f, v1);
|
||||||
|
assertEquals(0, ran.get());
|
||||||
}}
|
}}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -4884,7 +4883,7 @@ public class CompletableFutureTest extends JSR166TestCase {
|
||||||
for (boolean createIncomplete : new boolean[] { true, false })
|
for (boolean createIncomplete : new boolean[] { true, false })
|
||||||
for (Integer v1 : new Integer[] { 1, null })
|
for (Integer v1 : new Integer[] { 1, null })
|
||||||
{
|
{
|
||||||
final AtomicInteger a = new AtomicInteger(0);
|
final AtomicInteger ran = new AtomicInteger(0);
|
||||||
final CFException ex = new CFException();
|
final CFException ex = new CFException();
|
||||||
final CompletableFuture<Integer> f = new CompletableFuture<>();
|
final CompletableFuture<Integer> f = new CompletableFuture<>();
|
||||||
final DelegatedCompletionStage<Integer> d =
|
final DelegatedCompletionStage<Integer> d =
|
||||||
|
@ -4892,14 +4891,15 @@ public class CompletableFutureTest extends JSR166TestCase {
|
||||||
if (!createIncomplete) f.completeExceptionally(ex);
|
if (!createIncomplete) f.completeExceptionally(ex);
|
||||||
final CompletionStage<Integer> g = d.exceptionallyAsync
|
final CompletionStage<Integer> g = d.exceptionallyAsync
|
||||||
((Throwable t) -> {
|
((Throwable t) -> {
|
||||||
threadAssertSame(t, ex);
|
assertSame(t, ex);
|
||||||
a.getAndIncrement();
|
ran.getAndIncrement();
|
||||||
return v1;
|
return v1;
|
||||||
});
|
});
|
||||||
if (createIncomplete) f.completeExceptionally(ex);
|
if (createIncomplete) f.completeExceptionally(ex);
|
||||||
|
|
||||||
checkCompletedNormally(g.toCompletableFuture(), v1);
|
checkCompletedNormally(g.toCompletableFuture(), v1);
|
||||||
assertEquals(1, a.get());
|
checkCompletedExceptionally(f, ex);
|
||||||
|
assertEquals(1, ran.get());
|
||||||
}}
|
}}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -4910,7 +4910,7 @@ public class CompletableFutureTest extends JSR166TestCase {
|
||||||
public void testDefaultExceptionallyAsync_exceptionalCompletionActionFailed() {
|
public void testDefaultExceptionallyAsync_exceptionalCompletionActionFailed() {
|
||||||
for (boolean createIncomplete : new boolean[] { true, false })
|
for (boolean createIncomplete : new boolean[] { true, false })
|
||||||
{
|
{
|
||||||
final AtomicInteger a = new AtomicInteger(0);
|
final AtomicInteger ran = new AtomicInteger(0);
|
||||||
final CFException ex1 = new CFException();
|
final CFException ex1 = new CFException();
|
||||||
final CFException ex2 = new CFException();
|
final CFException ex2 = new CFException();
|
||||||
final CompletableFuture<Integer> f = new CompletableFuture<>();
|
final CompletableFuture<Integer> f = new CompletableFuture<>();
|
||||||
|
@ -4919,8 +4919,8 @@ public class CompletableFutureTest extends JSR166TestCase {
|
||||||
if (!createIncomplete) f.completeExceptionally(ex1);
|
if (!createIncomplete) f.completeExceptionally(ex1);
|
||||||
final CompletionStage<Integer> g = d.exceptionallyAsync
|
final CompletionStage<Integer> g = d.exceptionallyAsync
|
||||||
((Throwable t) -> {
|
((Throwable t) -> {
|
||||||
threadAssertSame(t, ex1);
|
assertSame(t, ex1);
|
||||||
a.getAndIncrement();
|
ran.getAndIncrement();
|
||||||
throw ex2;
|
throw ex2;
|
||||||
});
|
});
|
||||||
if (createIncomplete) f.completeExceptionally(ex1);
|
if (createIncomplete) f.completeExceptionally(ex1);
|
||||||
|
@ -4928,7 +4928,7 @@ public class CompletableFutureTest extends JSR166TestCase {
|
||||||
checkCompletedWithWrappedException(g.toCompletableFuture(), ex2);
|
checkCompletedWithWrappedException(g.toCompletableFuture(), ex2);
|
||||||
checkCompletedExceptionally(f, ex1);
|
checkCompletedExceptionally(f, ex1);
|
||||||
checkCompletedExceptionally(d.toCompletableFuture(), ex1);
|
checkCompletedExceptionally(d.toCompletableFuture(), ex1);
|
||||||
assertEquals(1, a.get());
|
assertEquals(1, ran.get());
|
||||||
}}
|
}}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -865,4 +865,20 @@ public class ConcurrentHashMapTest extends JSR166TestCase {
|
||||||
assertEquals(mapSize, map.size());
|
assertEquals(mapSize, map.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testReentrantComputeIfAbsent() {
|
||||||
|
ConcurrentHashMap<Integer, Integer> map = new ConcurrentHashMap<>(16);
|
||||||
|
try {
|
||||||
|
for (int i = 0; i < 100; i++) { // force a resize
|
||||||
|
map.computeIfAbsent(i, key -> findValue(map, key));
|
||||||
|
}
|
||||||
|
fail("recursive computeIfAbsent should throw IllegalStateException");
|
||||||
|
} catch (IllegalStateException success) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Integer findValue(ConcurrentHashMap<Integer, Integer> map,
|
||||||
|
Integer key) {
|
||||||
|
return (key % 5 == 0) ? key :
|
||||||
|
map.computeIfAbsent(key + 1, k -> findValue(map, k));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -136,7 +136,7 @@ public class ForkJoinPoolTest extends JSR166TestCase {
|
||||||
return n;
|
return n;
|
||||||
FibTask f1 = new FibTask(n - 1);
|
FibTask f1 = new FibTask(n - 1);
|
||||||
f1.fork();
|
f1.fork();
|
||||||
return (new FibTask(n - 2)).compute() + f1.join();
|
return new FibTask(n - 2).compute() + f1.join();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -144,13 +144,21 @@ import junit.framework.TestSuite;
|
||||||
*
|
*
|
||||||
* <ol>
|
* <ol>
|
||||||
*
|
*
|
||||||
* <li>All assertions in code running in generated threads must use
|
* <li>All code not running in the main test thread (manually spawned threads
|
||||||
* the forms {@link #threadFail}, {@link #threadAssertTrue}, {@link
|
* or the common fork join pool) must be checked for failure (and completion!).
|
||||||
* #threadAssertEquals}, or {@link #threadAssertNull}, (not
|
* Mechanisms that can be used to ensure this are:
|
||||||
* {@code fail}, {@code assertTrue}, etc.) It is OK (but not
|
* <ol>
|
||||||
* particularly recommended) for other code to use these forms too.
|
* <li>Signalling via a synchronizer like AtomicInteger or CountDownLatch
|
||||||
* Only the most typically used JUnit assertion methods are defined
|
* that the task completed normally, which is checked before returning from
|
||||||
* this way, but enough to live with.
|
* the test method in the main thread.
|
||||||
|
* <li>Using the forms {@link #threadFail}, {@link #threadAssertTrue},
|
||||||
|
* or {@link #threadAssertNull}, (not {@code fail}, {@code assertTrue}, etc.)
|
||||||
|
* Only the most typically used JUnit assertion methods are defined
|
||||||
|
* this way, but enough to live with.
|
||||||
|
* <li>Recording failure explicitly using {@link #threadUnexpectedException}
|
||||||
|
* or {@link #threadRecordFailure}.
|
||||||
|
* <li>Using a wrapper like CheckedRunnable that uses one the mechanisms above.
|
||||||
|
* </ol>
|
||||||
*
|
*
|
||||||
* <li>If you override {@link #setUp} or {@link #tearDown}, make sure
|
* <li>If you override {@link #setUp} or {@link #tearDown}, make sure
|
||||||
* to invoke {@code super.setUp} and {@code super.tearDown} within
|
* to invoke {@code super.setUp} and {@code super.tearDown} within
|
||||||
|
@ -1318,22 +1326,33 @@ public class JSR166TestCase extends TestCase {
|
||||||
/**
|
/**
|
||||||
* Spin-waits up to the specified number of milliseconds for the given
|
* Spin-waits up to the specified number of milliseconds for the given
|
||||||
* thread to enter a wait state: BLOCKED, WAITING, or TIMED_WAITING.
|
* thread to enter a wait state: BLOCKED, WAITING, or TIMED_WAITING.
|
||||||
|
* @param waitingForGodot if non-null, an additional condition to satisfy
|
||||||
*/
|
*/
|
||||||
void waitForThreadToEnterWaitState(Thread thread, long timeoutMillis) {
|
void waitForThreadToEnterWaitState(Thread thread, long timeoutMillis,
|
||||||
long startTime = 0L;
|
Callable<Boolean> waitingForGodot) {
|
||||||
for (;;) {
|
for (long startTime = 0L;;) {
|
||||||
Thread.State s = thread.getState();
|
switch (thread.getState()) {
|
||||||
if (s == Thread.State.BLOCKED ||
|
default: break;
|
||||||
s == Thread.State.WAITING ||
|
case BLOCKED: case WAITING: case TIMED_WAITING:
|
||||||
s == Thread.State.TIMED_WAITING)
|
try {
|
||||||
return;
|
if (waitingForGodot == null || waitingForGodot.call())
|
||||||
else if (s == Thread.State.TERMINATED)
|
return;
|
||||||
|
} catch (Throwable fail) { threadUnexpectedException(fail); }
|
||||||
|
break;
|
||||||
|
case TERMINATED:
|
||||||
fail("Unexpected thread termination");
|
fail("Unexpected thread termination");
|
||||||
else if (startTime == 0L)
|
}
|
||||||
|
|
||||||
|
if (startTime == 0L)
|
||||||
startTime = System.nanoTime();
|
startTime = System.nanoTime();
|
||||||
else if (millisElapsedSince(startTime) > timeoutMillis) {
|
else if (millisElapsedSince(startTime) > timeoutMillis) {
|
||||||
threadAssertTrue(thread.isAlive());
|
assertTrue(thread.isAlive());
|
||||||
fail("timed out waiting for thread to enter wait state");
|
if (waitingForGodot == null
|
||||||
|
|| thread.getState() == Thread.State.RUNNABLE)
|
||||||
|
fail("timed out waiting for thread to enter wait state");
|
||||||
|
else
|
||||||
|
fail("timed out waiting for condition, thread state="
|
||||||
|
+ thread.getState());
|
||||||
}
|
}
|
||||||
Thread.yield();
|
Thread.yield();
|
||||||
}
|
}
|
||||||
|
@ -1341,32 +1360,10 @@ public class JSR166TestCase extends TestCase {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Spin-waits up to the specified number of milliseconds for the given
|
* Spin-waits up to the specified number of milliseconds for the given
|
||||||
* thread to enter a wait state: BLOCKED, WAITING, or TIMED_WAITING,
|
* thread to enter a wait state: BLOCKED, WAITING, or TIMED_WAITING.
|
||||||
* and additionally satisfy the given condition.
|
|
||||||
*/
|
*/
|
||||||
void waitForThreadToEnterWaitState(
|
void waitForThreadToEnterWaitState(Thread thread, long timeoutMillis) {
|
||||||
Thread thread, long timeoutMillis, Callable<Boolean> waitingForGodot) {
|
waitForThreadToEnterWaitState(thread, timeoutMillis, null);
|
||||||
long startTime = 0L;
|
|
||||||
for (;;) {
|
|
||||||
Thread.State s = thread.getState();
|
|
||||||
if (s == Thread.State.BLOCKED ||
|
|
||||||
s == Thread.State.WAITING ||
|
|
||||||
s == Thread.State.TIMED_WAITING) {
|
|
||||||
try {
|
|
||||||
if (waitingForGodot.call())
|
|
||||||
return;
|
|
||||||
} catch (Throwable fail) { threadUnexpectedException(fail); }
|
|
||||||
}
|
|
||||||
else if (s == Thread.State.TERMINATED)
|
|
||||||
fail("Unexpected thread termination");
|
|
||||||
else if (startTime == 0L)
|
|
||||||
startTime = System.nanoTime();
|
|
||||||
else if (millisElapsedSince(startTime) > timeoutMillis) {
|
|
||||||
threadAssertTrue(thread.isAlive());
|
|
||||||
fail("timed out waiting for thread to enter wait state");
|
|
||||||
}
|
|
||||||
Thread.yield();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1374,7 +1371,7 @@ public class JSR166TestCase extends TestCase {
|
||||||
* enter a wait state: BLOCKED, WAITING, or TIMED_WAITING.
|
* enter a wait state: BLOCKED, WAITING, or TIMED_WAITING.
|
||||||
*/
|
*/
|
||||||
void waitForThreadToEnterWaitState(Thread thread) {
|
void waitForThreadToEnterWaitState(Thread thread) {
|
||||||
waitForThreadToEnterWaitState(thread, LONG_DELAY_MS);
|
waitForThreadToEnterWaitState(thread, LONG_DELAY_MS, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1382,8 +1379,8 @@ public class JSR166TestCase extends TestCase {
|
||||||
* enter a wait state: BLOCKED, WAITING, or TIMED_WAITING,
|
* enter a wait state: BLOCKED, WAITING, or TIMED_WAITING,
|
||||||
* and additionally satisfy the given condition.
|
* and additionally satisfy the given condition.
|
||||||
*/
|
*/
|
||||||
void waitForThreadToEnterWaitState(
|
void waitForThreadToEnterWaitState(Thread thread,
|
||||||
Thread thread, Callable<Boolean> waitingForGodot) {
|
Callable<Boolean> waitingForGodot) {
|
||||||
waitForThreadToEnterWaitState(thread, LONG_DELAY_MS, waitingForGodot);
|
waitForThreadToEnterWaitState(thread, LONG_DELAY_MS, waitingForGodot);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1491,11 +1488,12 @@ public class JSR166TestCase extends TestCase {
|
||||||
public final void run() {
|
public final void run() {
|
||||||
try {
|
try {
|
||||||
realRun();
|
realRun();
|
||||||
threadShouldThrow(exceptionClass.getSimpleName());
|
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
if (! exceptionClass.isInstance(t))
|
if (! exceptionClass.isInstance(t))
|
||||||
threadUnexpectedException(t);
|
threadUnexpectedException(t);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
threadShouldThrow(exceptionClass.getSimpleName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1505,12 +1503,13 @@ public class JSR166TestCase extends TestCase {
|
||||||
public final void run() {
|
public final void run() {
|
||||||
try {
|
try {
|
||||||
realRun();
|
realRun();
|
||||||
threadShouldThrow("InterruptedException");
|
|
||||||
} catch (InterruptedException success) {
|
} catch (InterruptedException success) {
|
||||||
threadAssertFalse(Thread.interrupted());
|
threadAssertFalse(Thread.interrupted());
|
||||||
|
return;
|
||||||
} catch (Throwable fail) {
|
} catch (Throwable fail) {
|
||||||
threadUnexpectedException(fail);
|
threadUnexpectedException(fail);
|
||||||
}
|
}
|
||||||
|
threadShouldThrow("InterruptedException");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1522,26 +1521,8 @@ public class JSR166TestCase extends TestCase {
|
||||||
return realCall();
|
return realCall();
|
||||||
} catch (Throwable fail) {
|
} catch (Throwable fail) {
|
||||||
threadUnexpectedException(fail);
|
threadUnexpectedException(fail);
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
}
|
throw new AssertionError("unreached");
|
||||||
}
|
|
||||||
|
|
||||||
public abstract class CheckedInterruptedCallable<T>
|
|
||||||
implements Callable<T> {
|
|
||||||
protected abstract T realCall() throws Throwable;
|
|
||||||
|
|
||||||
public final T call() {
|
|
||||||
try {
|
|
||||||
T result = realCall();
|
|
||||||
threadShouldThrow("InterruptedException");
|
|
||||||
return result;
|
|
||||||
} catch (InterruptedException success) {
|
|
||||||
threadAssertFalse(Thread.interrupted());
|
|
||||||
} catch (Throwable fail) {
|
|
||||||
threadUnexpectedException(fail);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1656,14 +1637,6 @@ public class JSR166TestCase extends TestCase {
|
||||||
public String call() { throw new NullPointerException(); }
|
public String call() { throw new NullPointerException(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class SmallPossiblyInterruptedRunnable extends CheckedRunnable {
|
|
||||||
protected void realRun() {
|
|
||||||
try {
|
|
||||||
delay(SMALL_DELAY_MS);
|
|
||||||
} catch (InterruptedException ok) {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Runnable possiblyInterruptedRunnable(final long timeoutMillis) {
|
public Runnable possiblyInterruptedRunnable(final long timeoutMillis) {
|
||||||
return new CheckedRunnable() {
|
return new CheckedRunnable() {
|
||||||
protected void realRun() {
|
protected void realRun() {
|
||||||
|
@ -1719,8 +1692,8 @@ public class JSR166TestCase extends TestCase {
|
||||||
return realCompute();
|
return realCompute();
|
||||||
} catch (Throwable fail) {
|
} catch (Throwable fail) {
|
||||||
threadUnexpectedException(fail);
|
threadUnexpectedException(fail);
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
throw new AssertionError("unreached");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -225,7 +225,7 @@ public class RecursiveTaskTest extends JSR166TestCase {
|
||||||
return n;
|
return n;
|
||||||
FibTask f1 = new FibTask(n - 1);
|
FibTask f1 = new FibTask(n - 1);
|
||||||
f1.fork();
|
f1.fork();
|
||||||
return (new FibTask(n - 2)).compute() + f1.join();
|
return new FibTask(n - 2).compute() + f1.join();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void publicSetRawResult(Integer result) {
|
public void publicSetRawResult(Integer result) {
|
||||||
|
@ -244,7 +244,7 @@ public class RecursiveTaskTest extends JSR166TestCase {
|
||||||
throw new FJException();
|
throw new FJException();
|
||||||
FailingFibTask f1 = new FailingFibTask(n - 1);
|
FailingFibTask f1 = new FailingFibTask(n - 1);
|
||||||
f1.fork();
|
f1.fork();
|
||||||
return (new FibTask(n - 2)).compute() + f1.join();
|
return new FibTask(n - 2).compute() + f1.join();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -676,7 +676,7 @@ public class ScheduledExecutorSubclassTest extends JSR166TestCase {
|
||||||
final CustomExecutor p = new CustomExecutor(1);
|
final CustomExecutor p = new CustomExecutor(1);
|
||||||
try (PoolCleaner cleaner = cleaner(p, releaser)) {
|
try (PoolCleaner cleaner = cleaner(p, releaser)) {
|
||||||
for (int i = 0; i < tasks.length; i++)
|
for (int i = 0; i < tasks.length; i++)
|
||||||
tasks[i] = p.schedule(new SmallPossiblyInterruptedRunnable(),
|
tasks[i] = p.schedule(possiblyInterruptedRunnable(SMALL_DELAY_MS),
|
||||||
LONG_DELAY_MS, MILLISECONDS);
|
LONG_DELAY_MS, MILLISECONDS);
|
||||||
int max = tasks.length;
|
int max = tasks.length;
|
||||||
if (tasks[4].cancel(true)) --max;
|
if (tasks[4].cancel(true)) --max;
|
||||||
|
|
|
@ -634,7 +634,7 @@ public class ScheduledExecutorTest extends JSR166TestCase {
|
||||||
final ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
|
final ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
|
||||||
try (PoolCleaner cleaner = cleaner(p, releaser)) {
|
try (PoolCleaner cleaner = cleaner(p, releaser)) {
|
||||||
for (int i = 0; i < tasks.length; i++)
|
for (int i = 0; i < tasks.length; i++)
|
||||||
tasks[i] = p.schedule(new SmallPossiblyInterruptedRunnable(),
|
tasks[i] = p.schedule(possiblyInterruptedRunnable(SMALL_DELAY_MS),
|
||||||
LONG_DELAY_MS, MILLISECONDS);
|
LONG_DELAY_MS, MILLISECONDS);
|
||||||
int max = tasks.length;
|
int max = tasks.length;
|
||||||
if (tasks[4].cancel(true)) --max;
|
if (tasks[4].cancel(true)) --max;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue