10888a09821a98ac0680fad765217302858e70fa4Paul Duffin/* 20888a09821a98ac0680fad765217302858e70fa4Paul Duffin * This file is a modified version of 30888a09821a98ac0680fad765217302858e70fa4Paul Duffin * http://gee.cs.oswego.edu/cgi-bin/viewcvs.cgi/jsr166/src/main/java/util/concurrent/AbstractExecutorService.java?revision=1.20 40888a09821a98ac0680fad765217302858e70fa4Paul Duffin * which contained the following notice: 50888a09821a98ac0680fad765217302858e70fa4Paul Duffin * 60888a09821a98ac0680fad765217302858e70fa4Paul Duffin * Written by Doug Lea with assistance from members of JCP JSR-166 70888a09821a98ac0680fad765217302858e70fa4Paul Duffin * Expert Group and released to the public domain, as explained at 80888a09821a98ac0680fad765217302858e70fa4Paul Duffin * http://creativecommons.org/licenses/publicdomain 90888a09821a98ac0680fad765217302858e70fa4Paul Duffin */ 100888a09821a98ac0680fad765217302858e70fa4Paul Duffin 110888a09821a98ac0680fad765217302858e70fa4Paul Duffinpackage java.util.concurrent; 120888a09821a98ac0680fad765217302858e70fa4Paul Duffin 130888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport java.util.*; 140888a09821a98ac0680fad765217302858e70fa4Paul Duffin 150888a09821a98ac0680fad765217302858e70fa4Paul Duffinpublic abstract class AbstractExecutorService implements ExecutorService { 160888a09821a98ac0680fad765217302858e70fa4Paul Duffin 170888a09821a98ac0680fad765217302858e70fa4Paul Duffin public Future<?> submit(Runnable task) { 180888a09821a98ac0680fad765217302858e70fa4Paul Duffin if (task == null) throw new NullPointerException(); 190888a09821a98ac0680fad765217302858e70fa4Paul Duffin FutureTask<Object> ftask = new FutureTask<Object>(task, null); 200888a09821a98ac0680fad765217302858e70fa4Paul Duffin execute(ftask); 210888a09821a98ac0680fad765217302858e70fa4Paul Duffin return ftask; 220888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 230888a09821a98ac0680fad765217302858e70fa4Paul Duffin 240888a09821a98ac0680fad765217302858e70fa4Paul Duffin public <T> Future<T> submit(Runnable task, T result) { 250888a09821a98ac0680fad765217302858e70fa4Paul Duffin if (task == null) throw new NullPointerException(); 260888a09821a98ac0680fad765217302858e70fa4Paul Duffin FutureTask<T> ftask = new FutureTask<T>(task, result); 270888a09821a98ac0680fad765217302858e70fa4Paul Duffin execute(ftask); 280888a09821a98ac0680fad765217302858e70fa4Paul Duffin return ftask; 290888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 300888a09821a98ac0680fad765217302858e70fa4Paul Duffin 310888a09821a98ac0680fad765217302858e70fa4Paul Duffin public <T> Future<T> submit(Callable<T> task) { 320888a09821a98ac0680fad765217302858e70fa4Paul Duffin if (task == null) throw new NullPointerException(); 330888a09821a98ac0680fad765217302858e70fa4Paul Duffin FutureTask<T> ftask = new FutureTask<T>(task); 340888a09821a98ac0680fad765217302858e70fa4Paul Duffin execute(ftask); 350888a09821a98ac0680fad765217302858e70fa4Paul Duffin return ftask; 360888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 370888a09821a98ac0680fad765217302858e70fa4Paul Duffin 380888a09821a98ac0680fad765217302858e70fa4Paul Duffin private <T> T doInvokeAny(Collection<? extends Callable<T>> tasks, 390888a09821a98ac0680fad765217302858e70fa4Paul Duffin boolean timed, long nanos) 400888a09821a98ac0680fad765217302858e70fa4Paul Duffin throws InterruptedException, ExecutionException, TimeoutException { 410888a09821a98ac0680fad765217302858e70fa4Paul Duffin if (tasks == null) 420888a09821a98ac0680fad765217302858e70fa4Paul Duffin throw new NullPointerException(); 430888a09821a98ac0680fad765217302858e70fa4Paul Duffin int ntasks = tasks.size(); 440888a09821a98ac0680fad765217302858e70fa4Paul Duffin if (ntasks == 0) 450888a09821a98ac0680fad765217302858e70fa4Paul Duffin throw new IllegalArgumentException(); 460888a09821a98ac0680fad765217302858e70fa4Paul Duffin List<Future<T>> futures= new ArrayList<Future<T>>(ntasks); 470888a09821a98ac0680fad765217302858e70fa4Paul Duffin ExecutorCompletionService<T> ecs = 480888a09821a98ac0680fad765217302858e70fa4Paul Duffin new ExecutorCompletionService<T>(this); 490888a09821a98ac0680fad765217302858e70fa4Paul Duffin 500888a09821a98ac0680fad765217302858e70fa4Paul Duffin try { 510888a09821a98ac0680fad765217302858e70fa4Paul Duffin ExecutionException ee = null; 520888a09821a98ac0680fad765217302858e70fa4Paul Duffin long lastTime = (timed)? System.nanoTime() : 0; 530888a09821a98ac0680fad765217302858e70fa4Paul Duffin Iterator<? extends Callable<T>> it = tasks.iterator(); 540888a09821a98ac0680fad765217302858e70fa4Paul Duffin 550888a09821a98ac0680fad765217302858e70fa4Paul Duffin futures.add(ecs.submit(it.next())); 560888a09821a98ac0680fad765217302858e70fa4Paul Duffin --ntasks; 570888a09821a98ac0680fad765217302858e70fa4Paul Duffin int active = 1; 580888a09821a98ac0680fad765217302858e70fa4Paul Duffin 590888a09821a98ac0680fad765217302858e70fa4Paul Duffin for (;;) { 600888a09821a98ac0680fad765217302858e70fa4Paul Duffin Future<T> f = ecs.poll(); 610888a09821a98ac0680fad765217302858e70fa4Paul Duffin if (f == null) { 620888a09821a98ac0680fad765217302858e70fa4Paul Duffin if (ntasks > 0) { 630888a09821a98ac0680fad765217302858e70fa4Paul Duffin --ntasks; 640888a09821a98ac0680fad765217302858e70fa4Paul Duffin futures.add(ecs.submit(it.next())); 650888a09821a98ac0680fad765217302858e70fa4Paul Duffin ++active; 660888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 670888a09821a98ac0680fad765217302858e70fa4Paul Duffin else if (active == 0) 680888a09821a98ac0680fad765217302858e70fa4Paul Duffin break; 690888a09821a98ac0680fad765217302858e70fa4Paul Duffin else if (timed) { 700888a09821a98ac0680fad765217302858e70fa4Paul Duffin f = ecs.poll(nanos, TimeUnit.NANOSECONDS); 710888a09821a98ac0680fad765217302858e70fa4Paul Duffin if (f == null) 720888a09821a98ac0680fad765217302858e70fa4Paul Duffin throw new TimeoutException(); 730888a09821a98ac0680fad765217302858e70fa4Paul Duffin long now = System.nanoTime(); 740888a09821a98ac0680fad765217302858e70fa4Paul Duffin nanos -= now - lastTime; 750888a09821a98ac0680fad765217302858e70fa4Paul Duffin lastTime = now; 760888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 770888a09821a98ac0680fad765217302858e70fa4Paul Duffin else 780888a09821a98ac0680fad765217302858e70fa4Paul Duffin f = ecs.take(); 790888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 800888a09821a98ac0680fad765217302858e70fa4Paul Duffin if (f != null) { 810888a09821a98ac0680fad765217302858e70fa4Paul Duffin --active; 820888a09821a98ac0680fad765217302858e70fa4Paul Duffin try { 830888a09821a98ac0680fad765217302858e70fa4Paul Duffin return f.get(); 840888a09821a98ac0680fad765217302858e70fa4Paul Duffin } catch (InterruptedException ie) { 850888a09821a98ac0680fad765217302858e70fa4Paul Duffin throw ie; 860888a09821a98ac0680fad765217302858e70fa4Paul Duffin } catch (ExecutionException eex) { 870888a09821a98ac0680fad765217302858e70fa4Paul Duffin ee = eex; 880888a09821a98ac0680fad765217302858e70fa4Paul Duffin } catch (RuntimeException rex) { 890888a09821a98ac0680fad765217302858e70fa4Paul Duffin ee = new ExecutionException(rex); 900888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 910888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 920888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 930888a09821a98ac0680fad765217302858e70fa4Paul Duffin 940888a09821a98ac0680fad765217302858e70fa4Paul Duffin if (ee == null) 950888a09821a98ac0680fad765217302858e70fa4Paul Duffin ee = new ExecutionException(); 960888a09821a98ac0680fad765217302858e70fa4Paul Duffin throw ee; 970888a09821a98ac0680fad765217302858e70fa4Paul Duffin 980888a09821a98ac0680fad765217302858e70fa4Paul Duffin } finally { 990888a09821a98ac0680fad765217302858e70fa4Paul Duffin for (Future<T> f : futures) 1000888a09821a98ac0680fad765217302858e70fa4Paul Duffin f.cancel(true); 1010888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 1020888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 1030888a09821a98ac0680fad765217302858e70fa4Paul Duffin 1040888a09821a98ac0680fad765217302858e70fa4Paul Duffin public <T> T invokeAny(Collection<? extends Callable<T>> tasks) 1050888a09821a98ac0680fad765217302858e70fa4Paul Duffin throws InterruptedException, ExecutionException { 1060888a09821a98ac0680fad765217302858e70fa4Paul Duffin try { 1070888a09821a98ac0680fad765217302858e70fa4Paul Duffin return doInvokeAny(tasks, false, 0); 1080888a09821a98ac0680fad765217302858e70fa4Paul Duffin } catch (TimeoutException cannotHappen) { 1090888a09821a98ac0680fad765217302858e70fa4Paul Duffin assert false; 1100888a09821a98ac0680fad765217302858e70fa4Paul Duffin return null; 1110888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 1120888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 1130888a09821a98ac0680fad765217302858e70fa4Paul Duffin 1140888a09821a98ac0680fad765217302858e70fa4Paul Duffin public <T> T invokeAny(Collection<? extends Callable<T>> tasks, 1150888a09821a98ac0680fad765217302858e70fa4Paul Duffin long timeout, TimeUnit unit) 1160888a09821a98ac0680fad765217302858e70fa4Paul Duffin throws InterruptedException, ExecutionException, TimeoutException { 1170888a09821a98ac0680fad765217302858e70fa4Paul Duffin return doInvokeAny(tasks, true, unit.toNanos(timeout)); 1180888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 1190888a09821a98ac0680fad765217302858e70fa4Paul Duffin 1200888a09821a98ac0680fad765217302858e70fa4Paul Duffin public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) 1210888a09821a98ac0680fad765217302858e70fa4Paul Duffin throws InterruptedException { 1220888a09821a98ac0680fad765217302858e70fa4Paul Duffin if (tasks == null) 1230888a09821a98ac0680fad765217302858e70fa4Paul Duffin throw new NullPointerException(); 1240888a09821a98ac0680fad765217302858e70fa4Paul Duffin List<Future<T>> futures = new ArrayList<Future<T>>(tasks.size()); 1250888a09821a98ac0680fad765217302858e70fa4Paul Duffin boolean done = false; 1260888a09821a98ac0680fad765217302858e70fa4Paul Duffin try { 1270888a09821a98ac0680fad765217302858e70fa4Paul Duffin for (Callable<T> t : tasks) { 1280888a09821a98ac0680fad765217302858e70fa4Paul Duffin FutureTask<T> f = new FutureTask<T>(t); 1290888a09821a98ac0680fad765217302858e70fa4Paul Duffin futures.add(f); 1300888a09821a98ac0680fad765217302858e70fa4Paul Duffin execute(f); 1310888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 1320888a09821a98ac0680fad765217302858e70fa4Paul Duffin for (Future<T> f : futures) { 1330888a09821a98ac0680fad765217302858e70fa4Paul Duffin if (!f.isDone()) { 1340888a09821a98ac0680fad765217302858e70fa4Paul Duffin try { 1350888a09821a98ac0680fad765217302858e70fa4Paul Duffin f.get(); 1360888a09821a98ac0680fad765217302858e70fa4Paul Duffin } catch (CancellationException ignore) { 1370888a09821a98ac0680fad765217302858e70fa4Paul Duffin } catch (ExecutionException ignore) { 1380888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 1390888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 1400888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 1410888a09821a98ac0680fad765217302858e70fa4Paul Duffin done = true; 1420888a09821a98ac0680fad765217302858e70fa4Paul Duffin return futures; 1430888a09821a98ac0680fad765217302858e70fa4Paul Duffin } finally { 1440888a09821a98ac0680fad765217302858e70fa4Paul Duffin if (!done) 1450888a09821a98ac0680fad765217302858e70fa4Paul Duffin for (Future<T> f : futures) 1460888a09821a98ac0680fad765217302858e70fa4Paul Duffin f.cancel(true); 1470888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 1480888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 1490888a09821a98ac0680fad765217302858e70fa4Paul Duffin 1500888a09821a98ac0680fad765217302858e70fa4Paul Duffin public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks, 1510888a09821a98ac0680fad765217302858e70fa4Paul Duffin long timeout, TimeUnit unit) 1520888a09821a98ac0680fad765217302858e70fa4Paul Duffin throws InterruptedException { 1530888a09821a98ac0680fad765217302858e70fa4Paul Duffin if (tasks == null || unit == null) 1540888a09821a98ac0680fad765217302858e70fa4Paul Duffin throw new NullPointerException(); 1550888a09821a98ac0680fad765217302858e70fa4Paul Duffin long nanos = unit.toNanos(timeout); 1560888a09821a98ac0680fad765217302858e70fa4Paul Duffin List<Future<T>> futures = new ArrayList<Future<T>>(tasks.size()); 1570888a09821a98ac0680fad765217302858e70fa4Paul Duffin boolean done = false; 1580888a09821a98ac0680fad765217302858e70fa4Paul Duffin try { 1590888a09821a98ac0680fad765217302858e70fa4Paul Duffin for (Callable<T> t : tasks) 1600888a09821a98ac0680fad765217302858e70fa4Paul Duffin futures.add(new FutureTask<T>(t)); 1610888a09821a98ac0680fad765217302858e70fa4Paul Duffin 1620888a09821a98ac0680fad765217302858e70fa4Paul Duffin long lastTime = System.nanoTime(); 1630888a09821a98ac0680fad765217302858e70fa4Paul Duffin 1640888a09821a98ac0680fad765217302858e70fa4Paul Duffin Iterator<Future<T>> it = futures.iterator(); 1650888a09821a98ac0680fad765217302858e70fa4Paul Duffin while (it.hasNext()) { 1660888a09821a98ac0680fad765217302858e70fa4Paul Duffin execute((Runnable)(it.next())); 1670888a09821a98ac0680fad765217302858e70fa4Paul Duffin long now = System.nanoTime(); 1680888a09821a98ac0680fad765217302858e70fa4Paul Duffin nanos -= now - lastTime; 1690888a09821a98ac0680fad765217302858e70fa4Paul Duffin lastTime = now; 1700888a09821a98ac0680fad765217302858e70fa4Paul Duffin if (nanos <= 0) 1710888a09821a98ac0680fad765217302858e70fa4Paul Duffin return futures; 1720888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 1730888a09821a98ac0680fad765217302858e70fa4Paul Duffin 1740888a09821a98ac0680fad765217302858e70fa4Paul Duffin for (Future<T> f : futures) { 1750888a09821a98ac0680fad765217302858e70fa4Paul Duffin if (!f.isDone()) { 1760888a09821a98ac0680fad765217302858e70fa4Paul Duffin if (nanos <= 0) 1770888a09821a98ac0680fad765217302858e70fa4Paul Duffin return futures; 1780888a09821a98ac0680fad765217302858e70fa4Paul Duffin try { 1790888a09821a98ac0680fad765217302858e70fa4Paul Duffin f.get(nanos, TimeUnit.NANOSECONDS); 1800888a09821a98ac0680fad765217302858e70fa4Paul Duffin } catch (CancellationException ignore) { 1810888a09821a98ac0680fad765217302858e70fa4Paul Duffin } catch (ExecutionException ignore) { 1820888a09821a98ac0680fad765217302858e70fa4Paul Duffin } catch (TimeoutException toe) { 1830888a09821a98ac0680fad765217302858e70fa4Paul Duffin return futures; 1840888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 1850888a09821a98ac0680fad765217302858e70fa4Paul Duffin long now = System.nanoTime(); 1860888a09821a98ac0680fad765217302858e70fa4Paul Duffin nanos -= now - lastTime; 1870888a09821a98ac0680fad765217302858e70fa4Paul Duffin lastTime = now; 1880888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 1890888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 1900888a09821a98ac0680fad765217302858e70fa4Paul Duffin done = true; 1910888a09821a98ac0680fad765217302858e70fa4Paul Duffin return futures; 1920888a09821a98ac0680fad765217302858e70fa4Paul Duffin } finally { 1930888a09821a98ac0680fad765217302858e70fa4Paul Duffin if (!done) 1940888a09821a98ac0680fad765217302858e70fa4Paul Duffin for (Future<T> f : futures) 1950888a09821a98ac0680fad765217302858e70fa4Paul Duffin f.cancel(true); 1960888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 1970888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 1980888a09821a98ac0680fad765217302858e70fa4Paul Duffin 1990888a09821a98ac0680fad765217302858e70fa4Paul Duffin} 200