12 |
|
import java.util.concurrent.ForkJoinTask; |
13 |
|
import java.util.concurrent.ForkJoinWorkerThread; |
14 |
|
import java.util.concurrent.RecursiveAction; |
15 |
+ |
import java.util.concurrent.ThreadLocalRandom; |
16 |
|
import java.util.concurrent.TimeUnit; |
17 |
|
import java.util.concurrent.TimeoutException; |
18 |
|
import static java.util.concurrent.TimeUnit.SECONDS; |
19 |
+ |
import java.util.Arrays; |
20 |
|
import java.util.HashSet; |
21 |
|
|
22 |
|
public class RecursiveActionTest extends JSR166TestCase { |
269 |
|
assertEquals(21, f.result); |
270 |
|
checkCompletedNormally(f); |
271 |
|
|
272 |
< |
f.reinitialize(); |
272 |
> |
f = new FibAction(8); |
273 |
|
f.cancel(true); |
274 |
|
assertSame(f, f.fork()); |
275 |
|
myself.interrupt(); |
282 |
|
checkCancelled(f); |
283 |
|
} |
284 |
|
|
285 |
< |
f.reinitialize(); |
285 |
> |
f = new FibAction(8); |
286 |
|
f.completeExceptionally(new FJException()); |
287 |
|
assertSame(f, f.fork()); |
288 |
|
myself.interrupt(); |
296 |
|
} |
297 |
|
|
298 |
|
// test quietlyJoin() |
299 |
< |
f.reinitialize(); |
299 |
> |
f = new FibAction(8); |
300 |
|
assertSame(f, f.fork()); |
301 |
|
myself.interrupt(); |
302 |
|
assertTrue(myself.isInterrupted()); |
305 |
|
assertEquals(21, f.result); |
306 |
|
checkCompletedNormally(f); |
307 |
|
|
308 |
< |
f.reinitialize(); |
308 |
> |
f = new FibAction(8); |
309 |
|
f.cancel(true); |
310 |
|
assertSame(f, f.fork()); |
311 |
|
myself.interrupt(); |
314 |
|
Thread.interrupted(); |
315 |
|
checkCancelled(f); |
316 |
|
|
317 |
< |
f.reinitialize(); |
317 |
> |
f = new FibAction(8); |
318 |
|
f.completeExceptionally(new FJException()); |
319 |
|
assertSame(f, f.fork()); |
320 |
|
myself.interrupt(); |
791 |
|
} |
792 |
|
|
793 |
|
/** |
794 |
< |
* A reinitialized task may be re-invoked |
794 |
> |
* A reinitialized normally completed task may be re-invoked |
795 |
|
*/ |
796 |
|
public void testReinitialize() { |
797 |
|
RecursiveAction a = new CheckedRecursiveAction() { |
811 |
|
} |
812 |
|
|
813 |
|
/** |
814 |
+ |
* A reinitialized abnormally completed task may be re-invoked |
815 |
+ |
*/ |
816 |
+ |
public void testReinitializeAbnormal() { |
817 |
+ |
RecursiveAction a = new CheckedRecursiveAction() { |
818 |
+ |
public void realCompute() { |
819 |
+ |
FailingFibAction f = new FailingFibAction(8); |
820 |
+ |
checkNotDone(f); |
821 |
+ |
|
822 |
+ |
for (int i = 0; i < 3; i++) { |
823 |
+ |
try { |
824 |
+ |
f.invoke(); |
825 |
+ |
shouldThrow(); |
826 |
+ |
} catch (FJException success) { |
827 |
+ |
checkCompletedAbnormally(f, success); |
828 |
+ |
} |
829 |
+ |
f.reinitialize(); |
830 |
+ |
checkNotDone(f); |
831 |
+ |
} |
832 |
+ |
}}; |
833 |
+ |
testInvokeOnPool(mainPool(), a); |
834 |
+ |
} |
835 |
+ |
|
836 |
+ |
/** |
837 |
|
* invoke task throws exception after invoking completeExceptionally |
838 |
|
*/ |
839 |
|
public void testCompleteExceptionally() { |
1197 |
|
testInvokeOnPool(asyncSingletonPool(), a); |
1198 |
|
} |
1199 |
|
|
1200 |
+ |
/** Demo from RecursiveAction javadoc */ |
1201 |
+ |
static class SortTask extends RecursiveAction { |
1202 |
+ |
final long[] array; final int lo, hi; |
1203 |
+ |
SortTask(long[] array, int lo, int hi) { |
1204 |
+ |
this.array = array; this.lo = lo; this.hi = hi; |
1205 |
+ |
} |
1206 |
+ |
SortTask(long[] array) { this(array, 0, array.length); } |
1207 |
+ |
protected void compute() { |
1208 |
+ |
if (hi - lo < THRESHOLD) |
1209 |
+ |
sortSequentially(lo, hi); |
1210 |
+ |
else { |
1211 |
+ |
int mid = (lo + hi) >>> 1; |
1212 |
+ |
invokeAll(new SortTask(array, lo, mid), |
1213 |
+ |
new SortTask(array, mid, hi)); |
1214 |
+ |
merge(lo, mid, hi); |
1215 |
+ |
} |
1216 |
+ |
} |
1217 |
+ |
// implementation details follow: |
1218 |
+ |
final static int THRESHOLD = 100; |
1219 |
+ |
void sortSequentially(int lo, int hi) { |
1220 |
+ |
Arrays.sort(array, lo, hi); |
1221 |
+ |
} |
1222 |
+ |
void merge(int lo, int mid, int hi) { |
1223 |
+ |
long[] buf = Arrays.copyOfRange(array, lo, mid); |
1224 |
+ |
for (int i = 0, j = lo, k = mid; i < buf.length; j++) |
1225 |
+ |
array[j] = (k == hi || buf[i] < array[k]) ? |
1226 |
+ |
buf[i++] : array[k++]; |
1227 |
+ |
} |
1228 |
+ |
} |
1229 |
+ |
|
1230 |
+ |
/** |
1231 |
+ |
* SortTask demo works as advertised |
1232 |
+ |
*/ |
1233 |
+ |
public void testSortTaskDemo() { |
1234 |
+ |
ThreadLocalRandom rnd = ThreadLocalRandom.current(); |
1235 |
+ |
long[] array = new long[1007]; |
1236 |
+ |
for (int i = 0; i < array.length; i++) |
1237 |
+ |
array[i] = rnd.nextLong(); |
1238 |
+ |
long[] arrayClone = array.clone(); |
1239 |
+ |
testInvokeOnPool(mainPool(), new SortTask(array)); |
1240 |
+ |
Arrays.sort(arrayClone); |
1241 |
+ |
assertTrue(Arrays.equals(array, arrayClone)); |
1242 |
+ |
} |
1243 |
|
} |