779 |
|
assertEquals(effectiveRemovePolicy, |
780 |
|
p.getRemoveOnCancelPolicy()); |
781 |
|
|
782 |
< |
// System.err.println("effectiveDelayedPolicy="+effectiveDelayedPolicy); |
783 |
< |
// System.err.println("effectivePeriodicPolicy="+effectivePeriodicPolicy); |
784 |
< |
// System.err.println("effectiveRemovePolicy="+effectiveRemovePolicy); |
782 |
> |
final boolean periodicTasksContinue = effectivePeriodicPolicy && rnd.nextBoolean(); |
783 |
|
|
784 |
|
// Strategy: Wedge the pool with one wave of "blocker" tasks, |
785 |
< |
// then add a second wave that waits in the queue. |
785 |
> |
// then add a second wave that waits in the queue until unblocked. |
786 |
|
final AtomicInteger ran = new AtomicInteger(0); |
787 |
|
final CountDownLatch poolBlocked = new CountDownLatch(poolSize); |
788 |
|
final CountDownLatch unblock = new CountDownLatch(1); |
789 |
+ |
final RuntimeException exception = new RuntimeException(); |
790 |
|
|
791 |
< |
class Task extends CheckedRunnable { |
792 |
< |
public void realRun() throws InterruptedException { |
793 |
< |
ran.getAndIncrement(); |
794 |
< |
poolBlocked.countDown(); |
795 |
< |
await(unblock); |
791 |
> |
class Task implements Runnable { |
792 |
> |
public void run() { |
793 |
> |
try { |
794 |
> |
ran.getAndIncrement(); |
795 |
> |
poolBlocked.countDown(); |
796 |
> |
await(unblock); |
797 |
> |
} catch (Throwable fail) { threadUnexpectedException(fail); } |
798 |
|
} |
799 |
|
} |
800 |
|
|
801 |
|
class PeriodicTask extends Task { |
802 |
|
PeriodicTask(int rounds) { this.rounds = rounds; } |
803 |
|
int rounds; |
804 |
< |
public void realRun() throws InterruptedException { |
805 |
< |
if (--rounds == 0) super.realRun(); |
804 |
> |
public void run() { |
805 |
> |
if (--rounds == 0) super.run(); |
806 |
> |
// throw exception to surely terminate this periodic task, |
807 |
> |
// but in a separate execution and in a detectable way. |
808 |
> |
if (rounds == -1) throw exception; |
809 |
|
} |
810 |
|
} |
811 |
|
|
827 |
|
await(poolBlocked); |
828 |
|
|
829 |
|
assertEquals(poolSize, ran.get()); |
830 |
+ |
assertEquals(poolSize, p.getActiveCount()); |
831 |
|
assertTrue(q.isEmpty()); |
832 |
|
|
833 |
|
// Add second wave of tasks. |
879 |
|
else |
880 |
|
assertTrue(delayeds.get(1).isCancelled()); |
881 |
|
|
882 |
< |
if (testImplementationDetails) { |
883 |
< |
if (effectivePeriodicPolicy) |
884 |
< |
// TODO: ensure periodic tasks continue executing |
885 |
< |
periodics.forEach( |
886 |
< |
f -> { |
882 |
< |
assertFalse(f.isDone()); |
882 |
> |
if (effectivePeriodicPolicy) |
883 |
> |
periodics.forEach( |
884 |
> |
f -> { |
885 |
> |
assertFalse(f.isDone()); |
886 |
> |
if (!periodicTasksContinue) { |
887 |
|
assertTrue(f.cancel(false)); |
888 |
< |
}); |
889 |
< |
else { |
890 |
< |
periodics.subList(0, 4).forEach(f -> assertFalse(f.isDone())); |
891 |
< |
periodics.subList(4, 8).forEach(f -> assertTrue(f.isCancelled())); |
892 |
< |
} |
888 |
> |
assertTrue(f.isCancelled()); |
889 |
> |
} |
890 |
> |
}); |
891 |
> |
else { |
892 |
> |
periodics.subList(0, 4).forEach(f -> assertFalse(f.isDone())); |
893 |
> |
periodics.subList(4, 8).forEach(f -> assertTrue(f.isCancelled())); |
894 |
|
} |
895 |
|
|
896 |
|
unblock.countDown(); // Release all pool threads |
901 |
|
|
902 |
|
assertTrue(q.isEmpty()); |
903 |
|
|
904 |
+ |
Stream.of(immediates, delayeds, periodics).flatMap(c -> c.stream()) |
905 |
+ |
.forEach(f -> assertTrue(f.isDone())); |
906 |
+ |
|
907 |
|
for (Future<?> f : immediates) assertNull(f.get()); |
908 |
|
|
909 |
|
assertNull(delayeds.get(0).get()); |
912 |
|
else |
913 |
|
assertTrue(delayeds.get(1).isCancelled()); |
914 |
|
|
915 |
< |
periodics.forEach(f -> assertTrue(f.isDone())); |
916 |
< |
periodics.forEach(f -> assertTrue(f.isCancelled())); |
915 |
> |
if (periodicTasksContinue) |
916 |
> |
periodics.forEach( |
917 |
> |
f -> { |
918 |
> |
try { f.get(); } |
919 |
> |
catch (ExecutionException success) { |
920 |
> |
assertSame(exception, success.getCause()); |
921 |
> |
} |
922 |
> |
catch (Throwable fail) { threadUnexpectedException(fail); } |
923 |
> |
}); |
924 |
> |
else |
925 |
> |
periodics.forEach(f -> assertTrue(f.isCancelled())); |
926 |
|
|
927 |
< |
assertEquals(poolSize + 1 + (effectiveDelayedPolicy ? 1 : 0), ran.get()); |
927 |
> |
assertEquals(poolSize + 1 |
928 |
> |
+ (effectiveDelayedPolicy ? 1 : 0) |
929 |
> |
+ (periodicTasksContinue ? 4 : 0), |
930 |
> |
ran.get()); |
931 |
|
} |
932 |
|
|
933 |
|
/** |