blob: 2c07c2a2f89593115744a526efd26990eac48971 [file] [log] [blame]
/*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
* http://creativecommons.org/publicdomain/zero/1.0/
*/
package jsr166;
import static java.util.concurrent.TimeUnit.SECONDS;
import java.util.HashSet;
import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.RecursiveTask;
import java.util.concurrent.TimeoutException;
import junit.framework.Test;
import junit.framework.TestSuite;
public class RecursiveTaskTest extends JSR166TestCase {
// android-note: Removed because the CTS runner does a bad job of
// retrying tests that have suite() declarations.
//
// public static void main(String[] args) {
// main(suite(), args);
// }
// public static Test suite() {
// return new TestSuite(RecursiveTaskTest.class);
// }
private static ForkJoinPool mainPool() {
return new ForkJoinPool();
}
private static ForkJoinPool singletonPool() {
return new ForkJoinPool(1);
}
private static ForkJoinPool asyncSingletonPool() {
return new ForkJoinPool(1,
ForkJoinPool.defaultForkJoinWorkerThreadFactory,
null, true);
}
private <T> T testInvokeOnPool(ForkJoinPool pool, RecursiveTask<T> a) {
try (PoolCleaner cleaner = cleaner(pool)) {
checkNotDone(a);
T result = pool.invoke(a);
checkCompletedNormally(a, result);
return result;
}
}
void checkNotDone(RecursiveTask a) {
assertFalse(a.isDone());
assertFalse(a.isCompletedNormally());
assertFalse(a.isCompletedAbnormally());
assertFalse(a.isCancelled());
assertNull(a.getException());
assertNull(a.getRawResult());
if (! ForkJoinTask.inForkJoinPool()) {
Thread.currentThread().interrupt();
try {
a.get();
shouldThrow();
} catch (InterruptedException success) {
} catch (Throwable fail) { threadUnexpectedException(fail); }
Thread.currentThread().interrupt();
try {
a.get(5L, SECONDS);
shouldThrow();
} catch (InterruptedException success) {
} catch (Throwable fail) { threadUnexpectedException(fail); }
}
try {
a.get(0L, SECONDS);
shouldThrow();
} catch (TimeoutException success) {
} catch (Throwable fail) { threadUnexpectedException(fail); }
}
<T> void checkCompletedNormally(RecursiveTask<T> a, T expected) {
assertTrue(a.isDone());
assertFalse(a.isCancelled());
assertTrue(a.isCompletedNormally());
assertFalse(a.isCompletedAbnormally());
assertNull(a.getException());
assertSame(expected, a.getRawResult());
assertSame(expected, a.join());
assertFalse(a.cancel(false));
assertFalse(a.cancel(true));
try {
assertSame(expected, a.get());
} catch (Throwable fail) { threadUnexpectedException(fail); }
try {
assertSame(expected, a.get(5L, SECONDS));
} catch (Throwable fail) { threadUnexpectedException(fail); }
}
/**
* Waits for the task to complete, and checks that when it does,
* it will have an Integer result equals to the given int.
*/
void checkCompletesNormally(RecursiveTask<Integer> a, int expected) {
Integer r = a.join();
assertEquals(expected, (int) r);
checkCompletedNormally(a, r);
}
/**
* Like checkCompletesNormally, but verifies that the task has
* already completed.
*/
void checkCompletedNormally(RecursiveTask<Integer> a, int expected) {
Integer r = a.getRawResult();
assertEquals(expected, (int) r);
checkCompletedNormally(a, r);
}
void checkCancelled(RecursiveTask a) {
assertTrue(a.isDone());
assertTrue(a.isCancelled());
assertFalse(a.isCompletedNormally());
assertTrue(a.isCompletedAbnormally());
assertTrue(a.getException() instanceof CancellationException);
assertNull(a.getRawResult());
try {
a.join();
shouldThrow();
} catch (CancellationException success) {
} catch (Throwable fail) { threadUnexpectedException(fail); }
try {
a.get();
shouldThrow();
} catch (CancellationException success) {
} catch (Throwable fail) { threadUnexpectedException(fail); }
try {
a.get(5L, SECONDS);
shouldThrow();
} catch (CancellationException success) {
} catch (Throwable fail) { threadUnexpectedException(fail); }
}
void checkCompletedAbnormally(RecursiveTask a, Throwable t) {
assertTrue(a.isDone());
assertFalse(a.isCancelled());
assertFalse(a.isCompletedNormally());
assertTrue(a.isCompletedAbnormally());
assertSame(t.getClass(), a.getException().getClass());
assertNull(a.getRawResult());
assertFalse(a.cancel(false));
assertFalse(a.cancel(true));
try {
a.join();
shouldThrow();
} catch (Throwable expected) {
assertSame(t.getClass(), expected.getClass());
}
try {
a.get();
shouldThrow();
} catch (ExecutionException success) {
assertSame(t.getClass(), success.getCause().getClass());
} catch (Throwable fail) { threadUnexpectedException(fail); }
try {
a.get(5L, SECONDS);
shouldThrow();
} catch (ExecutionException success) {
assertSame(t.getClass(), success.getCause().getClass());
} catch (Throwable fail) { threadUnexpectedException(fail); }
}
public static final class FJException extends RuntimeException {
public FJException() { super(); }
}
// An invalid return value for Fib
static final Integer NoResult = Integer.valueOf(-17);
// A simple recursive task for testing
final class FibTask extends CheckedRecursiveTask<Integer> {
final int number;
FibTask(int n) { number = n; }
public Integer realCompute() {
int n = number;
if (n <= 1)
return n;
FibTask f1 = new FibTask(n - 1);
f1.fork();
return (new FibTask(n - 2)).compute() + f1.join();
}
public void publicSetRawResult(Integer result) {
setRawResult(result);
}
}
// A recursive action failing in base case
final class FailingFibTask extends RecursiveTask<Integer> {
final int number;
int result;
FailingFibTask(int n) { number = n; }
public Integer compute() {
int n = number;
if (n <= 1)
throw new FJException();
FailingFibTask f1 = new FailingFibTask(n - 1);
f1.fork();
return (new FibTask(n - 2)).compute() + f1.join();
}
}
/**
* invoke returns value when task completes normally.
* isCompletedAbnormally and isCancelled return false for normally
* completed tasks. getRawResult of a completed non-null task
* returns value;
*/
public void testInvoke() {
RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
public Integer realCompute() {
FibTask f = new FibTask(8);
Integer r = f.invoke();
assertEquals(21, (int) r);
checkCompletedNormally(f, r);
return r;
}};
assertEquals(21, (int) testInvokeOnPool(mainPool(), a));
}
/**
* quietlyInvoke task returns when task completes normally.
* isCompletedAbnormally and isCancelled return false for normally
* completed tasks
*/
public void testQuietlyInvoke() {
RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
public Integer realCompute() {
FibTask f = new FibTask(8);
f.quietlyInvoke();
checkCompletedNormally(f, 21);
return NoResult;
}};
assertSame(NoResult, testInvokeOnPool(mainPool(), a));
}
/**
* join of a forked task returns when task completes
*/
public void testForkJoin() {
RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
public Integer realCompute() {
FibTask f = new FibTask(8);
assertSame(f, f.fork());
Integer r = f.join();
assertEquals(21, (int) r);
checkCompletedNormally(f, r);
return r;
}};
assertEquals(21, (int) testInvokeOnPool(mainPool(), a));
}
/**
* get of a forked task returns when task completes
*/
public void testForkGet() {
RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
public Integer realCompute() throws Exception {
FibTask f = new FibTask(8);
assertSame(f, f.fork());
Integer r = f.get();
assertEquals(21, (int) r);
checkCompletedNormally(f, r);
return r;
}};
assertEquals(21, (int) testInvokeOnPool(mainPool(), a));
}
/**
* timed get of a forked task returns when task completes
*/
public void testForkTimedGet() {
RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
public Integer realCompute() throws Exception {
FibTask f = new FibTask(8);
assertSame(f, f.fork());
Integer r = f.get(5L, SECONDS);
assertEquals(21, (int) r);
checkCompletedNormally(f, r);
return r;
}};
assertEquals(21, (int) testInvokeOnPool(mainPool(), a));
}
/**
* quietlyJoin of a forked task returns when task completes
*/
public void testForkQuietlyJoin() {
RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
public Integer realCompute() {
FibTask f = new FibTask(8);
assertSame(f, f.fork());
f.quietlyJoin();
Integer r = f.getRawResult();
assertEquals(21, (int) r);
checkCompletedNormally(f, r);
return r;
}};
assertEquals(21, (int) testInvokeOnPool(mainPool(), a));
}
/**
* helpQuiesce returns when tasks are complete.
* getQueuedTaskCount returns 0 when quiescent
*/
public void testForkHelpQuiesce() {
RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
public Integer realCompute() {
FibTask f = new FibTask(8);
assertSame(f, f.fork());
helpQuiesce();
while (!f.isDone()) // wait out race
;
assertEquals(0, getQueuedTaskCount());
checkCompletedNormally(f, 21);
return NoResult;
}};
assertSame(NoResult, testInvokeOnPool(mainPool(), a));
}
/**
* invoke task throws exception when task completes abnormally
*/
public void testAbnormalInvoke() {
RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
public Integer realCompute() {
FailingFibTask f = new FailingFibTask(8);
try {
f.invoke();
shouldThrow();
} catch (FJException success) {
checkCompletedAbnormally(f, success);
}
return NoResult;
}};
assertSame(NoResult, testInvokeOnPool(mainPool(), a));
}
/**
* quietlyInvoke task returns when task completes abnormally
*/
public void testAbnormalQuietlyInvoke() {
RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
public Integer realCompute() {
FailingFibTask f = new FailingFibTask(8);
f.quietlyInvoke();
assertTrue(f.getException() instanceof FJException);
checkCompletedAbnormally(f, f.getException());
return NoResult;
}};
assertSame(NoResult, testInvokeOnPool(mainPool(), a));
}
/**
* join of a forked task throws exception when task completes abnormally
*/
public void testAbnormalForkJoin() {
RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
public Integer realCompute() {
FailingFibTask f = new FailingFibTask(8);
assertSame(f, f.fork());
try {
Integer r = f.join();
shouldThrow();
} catch (FJException success) {
checkCompletedAbnormally(f, success);
}
return NoResult;
}};
assertSame(NoResult, testInvokeOnPool(mainPool(), a));
}
/**
* get of a forked task throws exception when task completes abnormally
*/
public void testAbnormalForkGet() {
RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
public Integer realCompute() throws Exception {
FailingFibTask f = new FailingFibTask(8);
assertSame(f, f.fork());
try {
Integer r = f.get();
shouldThrow();
} catch (ExecutionException success) {
Throwable cause = success.getCause();
assertTrue(cause instanceof FJException);
checkCompletedAbnormally(f, cause);
}
return NoResult;
}};
assertSame(NoResult, testInvokeOnPool(mainPool(), a));
}
/**
* timed get of a forked task throws exception when task completes abnormally
*/
public void testAbnormalForkTimedGet() {
RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
public Integer realCompute() throws Exception {
FailingFibTask f = new FailingFibTask(8);
assertSame(f, f.fork());
try {
Integer r = f.get(5L, SECONDS);
shouldThrow();
} catch (ExecutionException success) {
Throwable cause = success.getCause();
assertTrue(cause instanceof FJException);
checkCompletedAbnormally(f, cause);
}
return NoResult;
}};
assertSame(NoResult, testInvokeOnPool(mainPool(), a));
}
/**
* quietlyJoin of a forked task returns when task completes abnormally
*/
public void testAbnormalForkQuietlyJoin() {
RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
public Integer realCompute() {
FailingFibTask f = new FailingFibTask(8);
assertSame(f, f.fork());
f.quietlyJoin();
assertTrue(f.getException() instanceof FJException);
checkCompletedAbnormally(f, f.getException());
return NoResult;
}};
assertSame(NoResult, testInvokeOnPool(mainPool(), a));
}
/**
* invoke task throws exception when task cancelled
*/
public void testCancelledInvoke() {
RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
public Integer realCompute() {
FibTask f = new FibTask(8);
assertTrue(f.cancel(true));
try {
Integer r = f.invoke();
shouldThrow();
} catch (CancellationException success) {
checkCancelled(f);
}
return NoResult;
}};
assertSame(NoResult, testInvokeOnPool(mainPool(), a));
}
/**
* join of a forked task throws exception when task cancelled
*/
public void testCancelledForkJoin() {
RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
public Integer realCompute() {
FibTask f = new FibTask(8);
assertTrue(f.cancel(true));
assertSame(f, f.fork());
try {
Integer r = f.join();
shouldThrow();
} catch (CancellationException success) {
checkCancelled(f);
}
return NoResult;
}};
assertSame(NoResult, testInvokeOnPool(mainPool(), a));
}
/**
* get of a forked task throws exception when task cancelled
*/
public void testCancelledForkGet() {
RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
public Integer realCompute() throws Exception {
FibTask f = new FibTask(8);
assertTrue(f.cancel(true));
assertSame(f, f.fork());
try {
Integer r = f.get();
shouldThrow();
} catch (CancellationException success) {
checkCancelled(f);
}
return NoResult;
}};
assertSame(NoResult, testInvokeOnPool(mainPool(), a));
}
/**
* timed get of a forked task throws exception when task cancelled
*/
public void testCancelledForkTimedGet() {
RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
public Integer realCompute() throws Exception {
FibTask f = new FibTask(8);
assertTrue(f.cancel(true));
assertSame(f, f.fork());
try {
Integer r = f.get(5L, SECONDS);
shouldThrow();
} catch (CancellationException success) {
checkCancelled(f);
}
return NoResult;
}};
assertSame(NoResult, testInvokeOnPool(mainPool(), a));
}
/**
* quietlyJoin of a forked task returns when task cancelled
*/
public void testCancelledForkQuietlyJoin() {
RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
public Integer realCompute() {
FibTask f = new FibTask(8);
assertTrue(f.cancel(true));
assertSame(f, f.fork());
f.quietlyJoin();
checkCancelled(f);
return NoResult;
}};
assertSame(NoResult, testInvokeOnPool(mainPool(), a));
}
/**
* getPool of executing task returns its pool
*/
public void testGetPool() {
final ForkJoinPool mainPool = mainPool();
RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
public Integer realCompute() {
assertSame(mainPool, getPool());
return NoResult;
}};
assertSame(NoResult, testInvokeOnPool(mainPool, a));
}
/**
* getPool of non-FJ task returns null
*/
public void testGetPool2() {
RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
public Integer realCompute() {
assertNull(getPool());
return NoResult;
}};
assertSame(NoResult, a.invoke());
}
/**
* inForkJoinPool of executing task returns true
*/
public void testInForkJoinPool() {
RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
public Integer realCompute() {
assertTrue(inForkJoinPool());
return NoResult;
}};
assertSame(NoResult, testInvokeOnPool(mainPool(), a));
}
/**
* inForkJoinPool of non-FJ task returns false
*/
public void testInForkJoinPool2() {
RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
public Integer realCompute() {
assertFalse(inForkJoinPool());
return NoResult;
}};
assertSame(NoResult, a.invoke());
}
/**
* The value set by setRawResult is returned by getRawResult
*/
public void testSetRawResult() {
RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
public Integer realCompute() {
setRawResult(NoResult);
assertSame(NoResult, getRawResult());
return NoResult;
}
};
assertSame(NoResult, a.invoke());
}
/**
* A reinitialized normally completed task may be re-invoked
*/
public void testReinitialize() {
RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
public Integer realCompute() {
FibTask f = new FibTask(8);
checkNotDone(f);
for (int i = 0; i < 3; i++) {
Integer r = f.invoke();
assertEquals(21, (int) r);
checkCompletedNormally(f, r);
f.reinitialize();
f.publicSetRawResult(null);
checkNotDone(f);
}
return NoResult;
}};
assertSame(NoResult, testInvokeOnPool(mainPool(), a));
}
/**
* A reinitialized abnormally completed task may be re-invoked
*/
public void testReinitializeAbnormal() {
RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
public Integer realCompute() {
FailingFibTask f = new FailingFibTask(8);
checkNotDone(f);
for (int i = 0; i < 3; i++) {
try {
f.invoke();
shouldThrow();
} catch (FJException success) {
checkCompletedAbnormally(f, success);
}
f.reinitialize();
checkNotDone(f);
}
return NoResult;
}};
assertSame(NoResult, testInvokeOnPool(mainPool(), a));
}
/**
* invoke task throws exception after invoking completeExceptionally
*/
public void testCompleteExceptionally() {
RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
public Integer realCompute() {
FibTask f = new FibTask(8);
f.completeExceptionally(new FJException());
try {
Integer r = f.invoke();
shouldThrow();
} catch (FJException success) {
checkCompletedAbnormally(f, success);
}
return NoResult;
}};
assertSame(NoResult, testInvokeOnPool(mainPool(), a));
}
/**
* invoke task suppresses execution invoking complete
*/
public void testComplete() {
RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
public Integer realCompute() {
FibTask f = new FibTask(8);
f.complete(NoResult);
Integer r = f.invoke();
assertSame(NoResult, r);
checkCompletedNormally(f, NoResult);
return r;
}};
assertSame(NoResult, testInvokeOnPool(mainPool(), a));
}
/**
* invokeAll(t1, t2) invokes all task arguments
*/
public void testInvokeAll2() {
RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
public Integer realCompute() {
FibTask f = new FibTask(8);
FibTask g = new FibTask(9);
invokeAll(f, g);
checkCompletedNormally(f, 21);
checkCompletedNormally(g, 34);
return NoResult;
}};
assertSame(NoResult, testInvokeOnPool(mainPool(), a));
}
/**
* invokeAll(tasks) with 1 argument invokes task
*/
public void testInvokeAll1() {
RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
public Integer realCompute() {
FibTask f = new FibTask(8);
invokeAll(f);
checkCompletedNormally(f, 21);
return NoResult;
}};
assertSame(NoResult, testInvokeOnPool(mainPool(), a));
}
/**
* invokeAll(tasks) with > 2 argument invokes tasks
*/
public void testInvokeAll3() {
RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
public Integer realCompute() {
FibTask f = new FibTask(8);
FibTask g = new FibTask(9);
FibTask h = new FibTask(7);
invokeAll(f, g, h);
assertTrue(f.isDone());
assertTrue(g.isDone());
assertTrue(h.isDone());
checkCompletedNormally(f, 21);
checkCompletedNormally(g, 34);
checkCompletedNormally(h, 13);
return NoResult;
}};
assertSame(NoResult, testInvokeOnPool(mainPool(), a));
}
/**
* invokeAll(collection) invokes all tasks in the collection
*/
public void testInvokeAllCollection() {
RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
public Integer realCompute() {
FibTask f = new FibTask(8);
FibTask g = new FibTask(9);
FibTask h = new FibTask(7);
HashSet set = new HashSet();
set.add(f);
set.add(g);
set.add(h);
invokeAll(set);
assertTrue(f.isDone());
assertTrue(g.isDone());
assertTrue(h.isDone());
checkCompletedNormally(f, 21);
checkCompletedNormally(g, 34);
checkCompletedNormally(h, 13);
return NoResult;
}};
assertSame(NoResult, testInvokeOnPool(mainPool(), a));
}
/**
* invokeAll(tasks) with any null task throws NPE
*/
public void testInvokeAllNPE() {
RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
public Integer realCompute() {
FibTask f = new FibTask(8);
FibTask g = new FibTask(9);
FibTask h = null;
try {
invokeAll(f, g, h);
shouldThrow();
} catch (NullPointerException success) {}
return NoResult;
}};
assertSame(NoResult, testInvokeOnPool(mainPool(), a));
}
/**
* invokeAll(t1, t2) throw exception if any task does
*/
public void testAbnormalInvokeAll2() {
RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
public Integer realCompute() {
FibTask f = new FibTask(8);
FailingFibTask g = new FailingFibTask(9);
try {
invokeAll(f, g);
shouldThrow();
} catch (FJException success) {
checkCompletedAbnormally(g, success);
}
return NoResult;
}};
assertSame(NoResult, testInvokeOnPool(mainPool(), a));
}
/**
* invokeAll(tasks) with 1 argument throws exception if task does
*/
public void testAbnormalInvokeAll1() {
RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
public Integer realCompute() {
FailingFibTask g = new FailingFibTask(9);
try {
invokeAll(g);
shouldThrow();
} catch (FJException success) {
checkCompletedAbnormally(g, success);
}
return NoResult;
}};
assertSame(NoResult, testInvokeOnPool(mainPool(), a));
}
/**
* invokeAll(tasks) with > 2 argument throws exception if any task does
*/
public void testAbnormalInvokeAll3() {
RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
public Integer realCompute() {
FibTask f = new FibTask(8);
FailingFibTask g = new FailingFibTask(9);
FibTask h = new FibTask(7);
try {
invokeAll(f, g, h);
shouldThrow();
} catch (FJException success) {
checkCompletedAbnormally(g, success);
}
return NoResult;
}};
assertSame(NoResult, testInvokeOnPool(mainPool(), a));
}
/**
* invokeAll(collection) throws exception if any task does
*/
public void testAbnormalInvokeAllCollection() {
RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
public Integer realCompute() {
FailingFibTask f = new FailingFibTask(8);
FibTask g = new FibTask(9);
FibTask h = new FibTask(7);
HashSet set = new HashSet();
set.add(f);
set.add(g);
set.add(h);
try {
invokeAll(set);
shouldThrow();
} catch (FJException success) {
checkCompletedAbnormally(f, success);
}
return NoResult;
}};
assertSame(NoResult, testInvokeOnPool(mainPool(), a));
}
/**
* tryUnfork returns true for most recent unexecuted task,
* and suppresses execution
*/
public void testTryUnfork() {
RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
public Integer realCompute() {
FibTask g = new FibTask(9);
assertSame(g, g.fork());
FibTask f = new FibTask(8);
assertSame(f, f.fork());
assertTrue(f.tryUnfork());
helpQuiesce();
checkNotDone(f);
checkCompletedNormally(g, 34);
return NoResult;
}};
assertSame(NoResult, testInvokeOnPool(singletonPool(), a));
}
/**
* getSurplusQueuedTaskCount returns > 0 when
* there are more tasks than threads
*/
public void testGetSurplusQueuedTaskCount() {
RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
public Integer realCompute() {
FibTask h = new FibTask(7);
assertSame(h, h.fork());
FibTask g = new FibTask(9);
assertSame(g, g.fork());
FibTask f = new FibTask(8);
assertSame(f, f.fork());
assertTrue(getSurplusQueuedTaskCount() > 0);
helpQuiesce();
assertEquals(0, getSurplusQueuedTaskCount());
checkCompletedNormally(f, 21);
checkCompletedNormally(g, 34);
checkCompletedNormally(h, 13);
return NoResult;
}};
assertSame(NoResult, testInvokeOnPool(singletonPool(), a));
}
/**
* peekNextLocalTask returns most recent unexecuted task.
*/
public void testPeekNextLocalTask() {
RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
public Integer realCompute() {
FibTask g = new FibTask(9);
assertSame(g, g.fork());
FibTask f = new FibTask(8);
assertSame(f, f.fork());
assertSame(f, peekNextLocalTask());
checkCompletesNormally(f, 21);
helpQuiesce();
checkCompletedNormally(g, 34);
return NoResult;
}};
assertSame(NoResult, testInvokeOnPool(singletonPool(), a));
}
/**
* pollNextLocalTask returns most recent unexecuted task
* without executing it
*/
public void testPollNextLocalTask() {
RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
public Integer realCompute() {
FibTask g = new FibTask(9);
assertSame(g, g.fork());
FibTask f = new FibTask(8);
assertSame(f, f.fork());
assertSame(f, pollNextLocalTask());
helpQuiesce();
checkNotDone(f);
checkCompletedNormally(g, 34);
return NoResult;
}};
assertSame(NoResult, testInvokeOnPool(singletonPool(), a));
}
/**
* pollTask returns an unexecuted task without executing it
*/
public void testPollTask() {
RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
public Integer realCompute() {
FibTask g = new FibTask(9);
assertSame(g, g.fork());
FibTask f = new FibTask(8);
assertSame(f, f.fork());
assertSame(f, pollTask());
helpQuiesce();
checkNotDone(f);
checkCompletedNormally(g, 34);
return NoResult;
}};
assertSame(NoResult, testInvokeOnPool(singletonPool(), a));
}
/**
* peekNextLocalTask returns least recent unexecuted task in async mode
*/
public void testPeekNextLocalTaskAsync() {
RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
public Integer realCompute() {
FibTask g = new FibTask(9);
assertSame(g, g.fork());
FibTask f = new FibTask(8);
assertSame(f, f.fork());
assertSame(g, peekNextLocalTask());
assertEquals(21, (int) f.join());
helpQuiesce();
checkCompletedNormally(f, 21);
checkCompletedNormally(g, 34);
return NoResult;
}};
assertSame(NoResult, testInvokeOnPool(asyncSingletonPool(), a));
}
/**
* pollNextLocalTask returns least recent unexecuted task without
* executing it, in async mode
*/
public void testPollNextLocalTaskAsync() {
RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
public Integer realCompute() {
FibTask g = new FibTask(9);
assertSame(g, g.fork());
FibTask f = new FibTask(8);
assertSame(f, f.fork());
assertSame(g, pollNextLocalTask());
helpQuiesce();
checkCompletedNormally(f, 21);
checkNotDone(g);
return NoResult;
}};
assertSame(NoResult, testInvokeOnPool(asyncSingletonPool(), a));
}
/**
* pollTask returns an unexecuted task without executing it, in
* async mode
*/
public void testPollTaskAsync() {
RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
public Integer realCompute() {
FibTask g = new FibTask(9);
assertSame(g, g.fork());
FibTask f = new FibTask(8);
assertSame(f, f.fork());
assertSame(g, pollTask());
helpQuiesce();
checkCompletedNormally(f, 21);
checkNotDone(g);
return NoResult;
}};
assertSame(NoResult, testInvokeOnPool(asyncSingletonPool(), a));
}
}