18f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle/* 28f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle * Written by Doug Lea with assistance from members of JCP JSR-166 38f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle * Expert Group and released to the public domain, as explained at 48f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle * http://creativecommons.org/publicdomain/zero/1.0/ 58f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle * Other contributors include Andrew Wright, Jeffrey Hayes, 68f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle * Pat Fisher, Mike Judd. 78f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle */ 88f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle 98f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravlepackage jsr166; 108f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle 118f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravleimport junit.framework.*; 128f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravleimport java.util.*; 138f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravleimport java.util.concurrent.ArrayBlockingQueue; 148f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravleimport java.util.concurrent.Callable; 158f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravleimport java.util.concurrent.ExecutorCompletionService; 168f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravleimport java.util.concurrent.ExecutorService; 178f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravleimport java.util.concurrent.Executors; 188f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravleimport java.util.concurrent.Future; 198f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravleimport java.util.concurrent.FutureTask; 208f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravleimport java.util.concurrent.RunnableFuture; 218f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravleimport java.util.concurrent.ThreadPoolExecutor; 228f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravleimport java.util.concurrent.TimeUnit; 238f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravleimport static java.util.concurrent.TimeUnit.MILLISECONDS; 248f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravleimport java.util.concurrent.atomic.AtomicBoolean; 258f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravleimport java.security.*; 268f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle 278f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravlepublic class ExecutorCompletionServiceTest extends JSR166TestCase { 288f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle 298f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle /** 308f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle * Creating a new ECS with null Executor throw NPE 318f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle */ 328f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle public void testConstructorNPE() { 338f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle try { 348f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle ExecutorCompletionService ecs = new ExecutorCompletionService(null); 358f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle shouldThrow(); 368f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle } catch (NullPointerException success) {} 378f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle } 388f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle 398f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle /** 408f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle * Creating a new ECS with null queue throw NPE 418f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle */ 428f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle public void testConstructorNPE2() { 438f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle try { 448f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle ExecutorService e = Executors.newCachedThreadPool(); 458f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle ExecutorCompletionService ecs = new ExecutorCompletionService(e, null); 468f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle shouldThrow(); 478f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle } catch (NullPointerException success) {} 488f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle } 498f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle 508f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle /** 518f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle * Submitting a null callable throws NPE 528f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle */ 538f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle public void testSubmitNPE() { 548f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle ExecutorService e = Executors.newCachedThreadPool(); 558f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle ExecutorCompletionService ecs = new ExecutorCompletionService(e); 568f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle try { 578f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle Callable c = null; 588f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle ecs.submit(c); 598f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle shouldThrow(); 608f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle } catch (NullPointerException success) { 618f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle } finally { 628f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle joinPool(e); 638f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle } 648f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle } 658f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle 668f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle /** 678f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle * Submitting a null runnable throws NPE 688f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle */ 698f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle public void testSubmitNPE2() { 708f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle ExecutorService e = Executors.newCachedThreadPool(); 718f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle ExecutorCompletionService ecs = new ExecutorCompletionService(e); 728f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle try { 738f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle Runnable r = null; 748f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle ecs.submit(r, Boolean.TRUE); 758f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle shouldThrow(); 768f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle } catch (NullPointerException success) { 778f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle } finally { 788f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle joinPool(e); 798f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle } 808f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle } 818f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle 828f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle /** 838f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle * A taken submitted task is completed 848f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle */ 858f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle public void testTake() throws InterruptedException { 868f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle ExecutorService e = Executors.newCachedThreadPool(); 878f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle ExecutorCompletionService ecs = new ExecutorCompletionService(e); 888f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle try { 898f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle Callable c = new StringTask(); 908f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle ecs.submit(c); 918f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle Future f = ecs.take(); 928f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle assertTrue(f.isDone()); 938f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle } finally { 948f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle joinPool(e); 958f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle } 968f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle } 978f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle 988f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle /** 998f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle * Take returns the same future object returned by submit 1008f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle */ 1018f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle public void testTake2() throws InterruptedException { 1028f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle ExecutorService e = Executors.newCachedThreadPool(); 1038f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle ExecutorCompletionService ecs = new ExecutorCompletionService(e); 1048f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle try { 1058f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle Callable c = new StringTask(); 1068f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle Future f1 = ecs.submit(c); 1078f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle Future f2 = ecs.take(); 1088f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle assertSame(f1, f2); 1098f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle } finally { 1108f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle joinPool(e); 1118f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle } 1128f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle } 1138f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle 1148f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle /** 1158f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle * If poll returns non-null, the returned task is completed 1168f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle */ 1178f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle public void testPoll1() throws Exception { 1188f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle ExecutorService e = Executors.newCachedThreadPool(); 1198f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle ExecutorCompletionService ecs = new ExecutorCompletionService(e); 1208f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle try { 1218f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle assertNull(ecs.poll()); 1228f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle Callable c = new StringTask(); 1238f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle ecs.submit(c); 1248f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle 1258f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle long startTime = System.nanoTime(); 1268f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle Future f; 1278f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle while ((f = ecs.poll()) == null) { 1288f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle if (millisElapsedSince(startTime) > LONG_DELAY_MS) 1298f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle fail("timed out"); 1308f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle Thread.yield(); 1318f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle } 1328f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle assertTrue(f.isDone()); 1338f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle assertSame(TEST_STRING, f.get()); 1348f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle } finally { 1358f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle joinPool(e); 1368f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle } 1378f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle } 1388f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle 1398f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle /** 1408f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle * If timed poll returns non-null, the returned task is completed 1418f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle */ 1428f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle public void testPoll2() throws InterruptedException { 1438f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle ExecutorService e = Executors.newCachedThreadPool(); 1448f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle ExecutorCompletionService ecs = new ExecutorCompletionService(e); 1458f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle try { 1468f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle assertNull(ecs.poll()); 1478f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle Callable c = new StringTask(); 1488f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle ecs.submit(c); 1498f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle Future f = ecs.poll(SHORT_DELAY_MS, MILLISECONDS); 1508f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle if (f != null) 1518f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle assertTrue(f.isDone()); 1528f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle } finally { 1538f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle joinPool(e); 1548f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle } 1558f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle } 1568f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle 1578f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle /** 1588f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle * Submitting to underlying AES that overrides newTaskFor(Callable) 1598f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle * returns and eventually runs Future returned by newTaskFor. 1608f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle */ 1618f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle public void testNewTaskForCallable() throws InterruptedException { 1628f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle final AtomicBoolean done = new AtomicBoolean(false); 1638f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle class MyCallableFuture<V> extends FutureTask<V> { 1648f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle MyCallableFuture(Callable<V> c) { super(c); } 1658f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle protected void done() { done.set(true); } 1668f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle } 1678f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle ExecutorService e = new ThreadPoolExecutor( 1688f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle 1, 1, 30L, TimeUnit.SECONDS, 1698f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle new ArrayBlockingQueue<Runnable>(1)) { 1708f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle protected <T> RunnableFuture<T> newTaskFor(Callable<T> c) { 1718f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle return new MyCallableFuture<T>(c); 1728f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle }}; 1738f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle ExecutorCompletionService<String> ecs = 1748f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle new ExecutorCompletionService<String>(e); 1758f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle try { 1768f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle assertNull(ecs.poll()); 1778f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle Callable<String> c = new StringTask(); 1788f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle Future f1 = ecs.submit(c); 1798f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle assertTrue("submit must return MyCallableFuture", 1808f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle f1 instanceof MyCallableFuture); 1818f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle Future f2 = ecs.take(); 1828f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle assertSame("submit and take must return same objects", f1, f2); 1838f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle assertTrue("completed task must have set done", done.get()); 1848f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle } finally { 1858f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle joinPool(e); 1868f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle } 1878f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle } 1888f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle 1898f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle /** 1908f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle * Submitting to underlying AES that overrides newTaskFor(Runnable,T) 1918f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle * returns and eventually runs Future returned by newTaskFor. 1928f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle */ 1938f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle public void testNewTaskForRunnable() throws InterruptedException { 1948f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle final AtomicBoolean done = new AtomicBoolean(false); 1958f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle class MyRunnableFuture<V> extends FutureTask<V> { 1968f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle MyRunnableFuture(Runnable t, V r) { super(t, r); } 1978f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle protected void done() { done.set(true); } 1988f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle } 1998f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle ExecutorService e = new ThreadPoolExecutor( 2008f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle 1, 1, 30L, TimeUnit.SECONDS, 2018f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle new ArrayBlockingQueue<Runnable>(1)) { 2028f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle protected <T> RunnableFuture<T> newTaskFor(Runnable t, T r) { 2038f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle return new MyRunnableFuture<T>(t, r); 2048f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle }}; 2058f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle ExecutorCompletionService<String> ecs = 2068f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle new ExecutorCompletionService<String>(e); 2078f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle try { 2088f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle assertNull(ecs.poll()); 2098f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle Runnable r = new NoOpRunnable(); 2108f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle Future f1 = ecs.submit(r, null); 2118f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle assertTrue("submit must return MyRunnableFuture", 2128f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle f1 instanceof MyRunnableFuture); 2138f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle Future f2 = ecs.take(); 2148f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle assertSame("submit and take must return same objects", f1, f2); 2158f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle assertTrue("completed task must have set done", done.get()); 2168f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle } finally { 2178f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle joinPool(e); 2188f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle } 2198f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle } 2208f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle 2218f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle} 222