--- jsr166/src/test/tck/ThreadPoolExecutorTest.java 2003/12/22 00:48:56 1.12 +++ jsr166/src/test/tck/ThreadPoolExecutorTest.java 2005/05/09 17:15:27 1.22 @@ -1,8 +1,9 @@ /* - * Written by members of JCP JSR-166 Expert Group and released to the - * public domain. Use, modify, and redistribute this code in any way - * without acknowledgement. Other contributors include Andrew Wright, - * Jeffrey Hayes, Pat Fischer, Mike Judd. + * 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/licenses/publicdomain + * Other contributors include Andrew Wright, Jeffrey Hayes, + * Pat Fisher, Mike Judd. */ import java.util.concurrent.*; @@ -35,6 +36,15 @@ public class ThreadPoolExecutorTest exte } } + static class FailingThreadFactory implements ThreadFactory{ + int calls = 0; + public Thread newThread(Runnable r){ + if (++calls > 1) return null; + return new Thread(r); + } + } + + /** * execute successfully executes a runnable */ @@ -116,7 +126,7 @@ public class ThreadPoolExecutorTest exte unexpectedException(); } assertEquals(1, p2.getCompletedTaskCount()); - p2.shutdown(); + try { p2.shutdown(); } catch(SecurityException ok) { return; } joinPool(p2); } @@ -146,7 +156,6 @@ public class ThreadPoolExecutorTest exte ThreadFactory tf = new SimpleThreadFactory(); ThreadPoolExecutor p = new ThreadPoolExecutor(1,2,LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue(10), tf, new NoOpREHandler()); assertSame(tf, p.getThreadFactory()); - p.shutdown(); joinPool(p); } @@ -158,7 +167,6 @@ public class ThreadPoolExecutorTest exte ThreadFactory tf = new SimpleThreadFactory(); p.setThreadFactory(tf); assertSame(tf, p.getThreadFactory()); - p.shutdown(); joinPool(p); } @@ -184,7 +192,6 @@ public class ThreadPoolExecutorTest exte RejectedExecutionHandler h = new NoOpREHandler(); ThreadPoolExecutor p = new ThreadPoolExecutor(1,2,LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue(10), h); assertSame(h, p.getRejectedExecutionHandler()); - p.shutdown(); joinPool(p); } @@ -197,7 +204,6 @@ public class ThreadPoolExecutorTest exte RejectedExecutionHandler h = new NoOpREHandler(); p.setRejectedExecutionHandler(h); assertSame(h, p.getRejectedExecutionHandler()); - p.shutdown(); joinPool(p); } @@ -280,7 +286,7 @@ public class ThreadPoolExecutorTest exte ThreadPoolExecutor p1 = new ThreadPoolExecutor(1, 1, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue(10)); assertFalse(p1.isShutdown()); - p1.shutdown(); + try { p1.shutdown(); } catch(SecurityException ok) { return; } assertTrue(p1.isShutdown()); joinPool(p1); } @@ -295,7 +301,7 @@ public class ThreadPoolExecutorTest exte try { p1.execute(new MediumRunnable()); } finally { - p1.shutdown(); + try { p1.shutdown(); } catch(SecurityException ok) { return; } } try { assertTrue(p1.awaitTermination(LONG_DELAY_MS, TimeUnit.MILLISECONDS)); @@ -315,7 +321,7 @@ public class ThreadPoolExecutorTest exte p1.execute(new SmallRunnable()); assertFalse(p1.isTerminating()); } finally { - p1.shutdown(); + try { p1.shutdown(); } catch(SecurityException ok) { return; } } try { assertTrue(p1.awaitTermination(LONG_DELAY_MS, TimeUnit.MILLISECONDS)); @@ -343,6 +349,8 @@ public class ThreadPoolExecutorTest exte assertSame(q, wq); assertFalse(wq.contains(tasks[0])); assertTrue(wq.contains(tasks[4])); + for (int i = 1; i < 5; ++i) + tasks[i].cancel(true); p1.shutdownNow(); } catch(Exception e) { unexpectedException(); @@ -373,7 +381,6 @@ public class ThreadPoolExecutorTest exte assertTrue(q.contains(tasks[3])); assertTrue(p1.remove(tasks[3])); assertFalse(q.contains(tasks[3])); - p1.shutdownNow(); } catch(Exception e) { unexpectedException(); } finally { @@ -396,7 +403,6 @@ public class ThreadPoolExecutorTest exte p1.purge(); long count = p1.getTaskCount(); assertTrue(count >= 2 && count < 5); - p1.shutdownNow(); joinPool(p1); } @@ -411,7 +417,10 @@ public class ThreadPoolExecutorTest exte p1.execute(new MediumPossiblyInterruptedRunnable()); } finally { - l = p1.shutdownNow(); + try { + l = p1.shutdownNow(); + } catch (SecurityException ok) { return; } + } assertTrue(p1.isShutdown()); assertTrue(l.size() <= 4); @@ -772,7 +781,7 @@ public class ThreadPoolExecutorTest exte for(int i = 1; i < 5; ++i) { assertTrue(tasks[i].done); } - p.shutdownNow(); + try { p.shutdownNow(); } catch(SecurityException ok) { return; } } catch(RejectedExecutionException ex){ unexpectedException(); } finally { @@ -799,7 +808,7 @@ public class ThreadPoolExecutorTest exte for(int i = 0; i < 5; ++i){ assertFalse(tasks[i].done); } - p.shutdownNow(); + try { p.shutdownNow(); } catch(SecurityException ok) { return; } } catch(RejectedExecutionException ex){ unexpectedException(); } finally { @@ -822,7 +831,7 @@ public class ThreadPoolExecutorTest exte p.execute(r3); assertFalse(p.getQueue().contains(r2)); assertTrue(p.getQueue().contains(r3)); - p.shutdownNow(); + try { p.shutdownNow(); } catch(SecurityException ok) { return; } } catch(RejectedExecutionException ex){ unexpectedException(); } finally { @@ -836,7 +845,7 @@ public class ThreadPoolExecutorTest exte public void testRejectedExecutionExceptionOnShutdown() { ThreadPoolExecutor tpe = new ThreadPoolExecutor(1,1,LONG_DELAY_MS, TimeUnit.MILLISECONDS,new ArrayBlockingQueue(1)); - tpe.shutdown(); + try { tpe.shutdown(); } catch(SecurityException ok) { return; } try { tpe.execute(new NoOpRunnable()); shouldThrow(); @@ -852,7 +861,7 @@ public class ThreadPoolExecutorTest exte RejectedExecutionHandler h = new ThreadPoolExecutor.CallerRunsPolicy(); ThreadPoolExecutor p = new ThreadPoolExecutor(1,1, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue(1), h); - p.shutdown(); + try { p.shutdown(); } catch(SecurityException ok) { return; } try { TrackedNoOpRunnable r = new TrackedNoOpRunnable(); p.execute(r); @@ -871,7 +880,7 @@ public class ThreadPoolExecutorTest exte RejectedExecutionHandler h = new ThreadPoolExecutor.DiscardPolicy(); ThreadPoolExecutor p = new ThreadPoolExecutor(1,1, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue(1), h); - p.shutdown(); + try { p.shutdown(); } catch(SecurityException ok) { return; } try { TrackedNoOpRunnable r = new TrackedNoOpRunnable(); p.execute(r); @@ -891,7 +900,7 @@ public class ThreadPoolExecutorTest exte RejectedExecutionHandler h = new ThreadPoolExecutor.DiscardOldestPolicy(); ThreadPoolExecutor p = new ThreadPoolExecutor(1,1, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue(1), h); - p.shutdown(); + try { p.shutdown(); } catch(SecurityException ok) { return; } try { TrackedNoOpRunnable r = new TrackedNoOpRunnable(); p.execute(r); @@ -931,7 +940,7 @@ public class ThreadPoolExecutorTest exte shouldThrow(); } catch(IllegalArgumentException success){ } finally { - tpe.shutdown(); + try { tpe.shutdown(); } catch(SecurityException ok) { return; } } joinPool(tpe); } @@ -950,7 +959,7 @@ public class ThreadPoolExecutorTest exte shouldThrow(); } catch(IllegalArgumentException success){ } finally { - tpe.shutdown(); + try { tpe.shutdown(); } catch(SecurityException ok) { return; } } joinPool(tpe); } @@ -969,7 +978,7 @@ public class ThreadPoolExecutorTest exte shouldThrow(); } catch(IllegalArgumentException success){ } finally { - tpe.shutdown(); + try { tpe.shutdown(); } catch(SecurityException ok) { return; } } joinPool(tpe); } @@ -990,7 +999,7 @@ public class ThreadPoolExecutorTest exte shouldThrow(); } catch(IllegalArgumentException success){ } finally { - tpe.shutdown(); + try { tpe.shutdown(); } catch(SecurityException ok) { return; } } joinPool(tpe); } @@ -1000,7 +1009,7 @@ public class ThreadPoolExecutorTest exte */ public void testTerminated() { ExtendedTPE tpe = new ExtendedTPE(); - tpe.shutdown(); + try { tpe.shutdown(); } catch(SecurityException ok) { return; } assertTrue(tpe.terminatedCalled); joinPool(tpe); } @@ -1017,7 +1026,7 @@ public class ThreadPoolExecutorTest exte assertTrue(r.done); assertTrue(tpe.beforeCalled); assertTrue(tpe.afterCalled); - tpe.shutdown(); + try { tpe.shutdown(); } catch(SecurityException ok) { return; } } catch(Exception ex) { unexpectedException(); @@ -1264,4 +1273,303 @@ public class ThreadPoolExecutorTest exte } + + /** + * timed invokeAny(null) throws NPE + */ + public void testTimedInvokeAny1() { + ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue(10)); + try { + e.invokeAny(null, MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS); + } catch (NullPointerException success) { + } catch(Exception ex) { + unexpectedException(); + } finally { + joinPool(e); + } + } + + /** + * timed invokeAny(,,null) throws NPE + */ + public void testTimedInvokeAnyNullTimeUnit() { + ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue(10)); + try { + ArrayList> l = new ArrayList>(); + l.add(new StringTask()); + e.invokeAny(l, MEDIUM_DELAY_MS, null); + } catch (NullPointerException success) { + } catch(Exception ex) { + unexpectedException(); + } finally { + joinPool(e); + } + } + + /** + * timed invokeAny(empty collection) throws IAE + */ + public void testTimedInvokeAny2() { + ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue(10)); + try { + e.invokeAny(new ArrayList>(), MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS); + } catch (IllegalArgumentException success) { + } catch(Exception ex) { + unexpectedException(); + } finally { + joinPool(e); + } + } + + /** + * timed invokeAny(c) throws NPE if c has null elements + */ + public void testTimedInvokeAny3() { + ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue(10)); + try { + ArrayList> l = new ArrayList>(); + l.add(new StringTask()); + l.add(null); + e.invokeAny(l, MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS); + } catch (NullPointerException success) { + } catch(Exception ex) { + ex.printStackTrace(); + unexpectedException(); + } finally { + joinPool(e); + } + } + + /** + * timed invokeAny(c) throws ExecutionException if no task completes + */ + public void testTimedInvokeAny4() { + ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue(10)); + try { + ArrayList> l = new ArrayList>(); + l.add(new NPETask()); + e.invokeAny(l, MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS); + } catch(ExecutionException success) { + } catch(Exception ex) { + unexpectedException(); + } finally { + joinPool(e); + } + } + + /** + * timed invokeAny(c) returns result of some task + */ + public void testTimedInvokeAny5() { + ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue(10)); + try { + ArrayList> l = new ArrayList>(); + l.add(new StringTask()); + l.add(new StringTask()); + String result = e.invokeAny(l, MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS); + assertSame(TEST_STRING, result); + } catch (ExecutionException success) { + } catch(Exception ex) { + unexpectedException(); + } finally { + joinPool(e); + } + } + + /** + * timed invokeAll(null) throws NPE + */ + public void testTimedInvokeAll1() { + ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue(10)); + try { + e.invokeAll(null, MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS); + } catch (NullPointerException success) { + } catch(Exception ex) { + unexpectedException(); + } finally { + joinPool(e); + } + } + + /** + * timed invokeAll(,,null) throws NPE + */ + public void testTimedInvokeAllNullTimeUnit() { + ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue(10)); + try { + ArrayList> l = new ArrayList>(); + l.add(new StringTask()); + e.invokeAll(l, MEDIUM_DELAY_MS, null); + } catch (NullPointerException success) { + } catch(Exception ex) { + unexpectedException(); + } finally { + joinPool(e); + } + } + + /** + * timed invokeAll(empty collection) returns empty collection + */ + public void testTimedInvokeAll2() { + ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue(10)); + try { + List> r = e.invokeAll(new ArrayList>(), MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS); + assertTrue(r.isEmpty()); + } catch(Exception ex) { + unexpectedException(); + } finally { + joinPool(e); + } + } + + /** + * timed invokeAll(c) throws NPE if c has null elements + */ + public void testTimedInvokeAll3() { + ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue(10)); + try { + ArrayList> l = new ArrayList>(); + l.add(new StringTask()); + l.add(null); + e.invokeAll(l, MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS); + } catch (NullPointerException success) { + } catch(Exception ex) { + unexpectedException(); + } finally { + joinPool(e); + } + } + + /** + * get of element of invokeAll(c) throws exception on failed task + */ + public void testTimedInvokeAll4() { + ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue(10)); + try { + ArrayList> l = new ArrayList>(); + l.add(new NPETask()); + List> result = e.invokeAll(l, MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS); + assertEquals(1, result.size()); + for (Iterator> it = result.iterator(); it.hasNext();) + it.next().get(); + } catch(ExecutionException success) { + } catch(Exception ex) { + unexpectedException(); + } finally { + joinPool(e); + } + } + + /** + * timed invokeAll(c) returns results of all completed tasks + */ + public void testTimedInvokeAll5() { + ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue(10)); + try { + ArrayList> l = new ArrayList>(); + l.add(new StringTask()); + l.add(new StringTask()); + List> result = e.invokeAll(l, MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS); + assertEquals(2, result.size()); + for (Iterator> it = result.iterator(); it.hasNext();) + assertSame(TEST_STRING, it.next().get()); + } catch (ExecutionException success) { + } catch(Exception ex) { + unexpectedException(); + } finally { + joinPool(e); + } + } + + /** + * timed invokeAll(c) cancels tasks not completed by timeout + */ + public void testTimedInvokeAll6() { + ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue(10)); + try { + ArrayList> l = new ArrayList>(); + l.add(new StringTask()); + l.add(Executors.callable(new MediumPossiblyInterruptedRunnable(), TEST_STRING)); + l.add(new StringTask()); + List> result = e.invokeAll(l, SHORT_DELAY_MS, TimeUnit.MILLISECONDS); + assertEquals(3, result.size()); + Iterator> it = result.iterator(); + Future f1 = it.next(); + Future f2 = it.next(); + Future f3 = it.next(); + assertTrue(f1.isDone()); + assertTrue(f2.isDone()); + assertTrue(f3.isDone()); + assertFalse(f1.isCancelled()); + assertTrue(f2.isCancelled()); + } catch(Exception ex) { + unexpectedException(); + } finally { + joinPool(e); + } + } + + /** + * Execution continues if there is at least one thread even if + * thread factory fails to create more + */ + public void testFailingThreadFactory() { + ExecutorService e = new ThreadPoolExecutor(100, 100, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new LinkedBlockingQueue(), new FailingThreadFactory()); + try { + ArrayList> l = new ArrayList>(); + for (int k = 0; k < 100; ++k) { + e.execute(new NoOpRunnable()); + } + Thread.sleep(LONG_DELAY_MS); + } catch(Exception ex) { + unexpectedException(); + } finally { + joinPool(e); + } + } + + /** + * allowsCoreThreadTimeOut is by default false. + */ + public void testAllowsCoreThreadTimeOut() { + ThreadPoolExecutor tpe = new ThreadPoolExecutor(2, 2, 1000, TimeUnit.MILLISECONDS, new ArrayBlockingQueue(10)); + assertFalse(tpe.allowsCoreThreadTimeOut()); + joinPool(tpe); + } + + /** + * allowCoreThreadTimeOut(true) causes idle threads to time out + */ + public void testAllowCoreThreadTimeOut_true() { + ThreadPoolExecutor tpe = new ThreadPoolExecutor(2, 10, 10, TimeUnit.MILLISECONDS, new ArrayBlockingQueue(10)); + tpe.allowCoreThreadTimeOut(true); + tpe.execute(new NoOpRunnable()); + try { + Thread.sleep(MEDIUM_DELAY_MS); + assertEquals(0, tpe.getPoolSize()); + } catch(InterruptedException e){ + unexpectedException(); + } finally { + joinPool(tpe); + } + } + + /** + * allowCoreThreadTimeOut(false) causes idle threads not to time out + */ + public void testAllowCoreThreadTimeOut_false() { + ThreadPoolExecutor tpe = new ThreadPoolExecutor(2, 10, 10, TimeUnit.MILLISECONDS, new ArrayBlockingQueue(10)); + tpe.allowCoreThreadTimeOut(false); + tpe.execute(new NoOpRunnable()); + try { + Thread.sleep(MEDIUM_DELAY_MS); + assertTrue(tpe.getPoolSize() >= 1); + } catch(InterruptedException e){ + unexpectedException(); + } finally { + joinPool(tpe); + } + } + }