Coverage Report - org.webslinger.lang.ExecutionPool
 
Classes in this File Line Coverage Branch Coverage Complexity
ExecutionPool
53%
19/36
80%
4/5
0
ExecutionPool$1
100%
7/7
N/A
0
ExecutionPool$2
100%
3/3
N/A
0
ExecutionPool$3
100%
5/5
N/A
0
ExecutionPool$AtExitExecutor
60%
3/5
N/A
0
ExecutionPool$AtExitExecutorService
25%
4/16
N/A
0
ExecutionPool$AtExitScheduledExecutorService
57%
4/7
N/A
0
 
 1  
 package org.webslinger.lang;
 2  
 
 3  
 import java.lang.management.ManagementFactory;
 4  
 import java.util.ArrayList;
 5  
 import java.util.Collection;
 6  
 import java.util.LinkedHashSet;
 7  
 import java.util.List;
 8  
 import java.util.concurrent.Callable;
 9  
 import java.util.concurrent.CompletionService;
 10  
 import java.util.concurrent.ExecutionException;
 11  
 import java.util.concurrent.Executor;
 12  
 import java.util.concurrent.ExecutorCompletionService;
 13  
 import java.util.concurrent.Executors;
 14  
 import java.util.concurrent.ExecutorService;
 15  
 import java.util.concurrent.Future;
 16  
 import java.util.concurrent.ScheduledExecutorService;
 17  
 import java.util.concurrent.ScheduledFuture;
 18  
 import java.util.concurrent.ThreadFactory;
 19  
 import java.util.concurrent.TimeoutException;
 20  
 import java.util.concurrent.TimeUnit;
 21  
 
 22  0
 public final class ExecutionPool {
 23  1
     private static final ScheduledExecutorService executor = getNewOptimalExecutor("ThreadPool");
 24  1
     private static final ThreadLocal<LinkedHashSet<ThreadSingletonState>> atExit = new ThreadLocal<LinkedHashSet<ThreadSingletonState>>();
 25  
 
 26  
     public static ScheduledExecutorService getExecutor(final String namePrefix, int threadCount) {
 27  2
         return new AtExitScheduledExecutorService(Executors.newScheduledThreadPool(
 28  
             threadCount,
 29  2
             new ThreadFactory() {
 30  2
                 private int count = 0;
 31  
                 public Thread newThread(Runnable r) {
 32  12
                     Thread t = new Thread(r);
 33  12
                     t.setDaemon(true);
 34  12
                     t.setPriority(Thread.NORM_PRIORITY);
 35  12
                     t.setName(namePrefix + "-" + count++);
 36  12
                     return t;
 37  
                 }
 38  
             }
 39  
         ));
 40  
     }
 41  
 
 42  
     public static ScheduledExecutorService getNewOptimalExecutor(String namePrefix) {
 43  2
         return getExecutor(namePrefix, ManagementFactory.getOperatingSystemMXBean().getAvailableProcessors() * 2);
 44  
     }
 45  
 
 46  
     public static CompletionService newCompletionService() {
 47  0
         return new ExecutorCompletionService(executor);
 48  
     }
 49  
 
 50  
     public static <T> Callable<T> wrapForAtExit(final Callable<T> command) {
 51  65
         return new Callable<T>() {
 52  
             public T call() throws Exception {
 53  
                 try {
 54  65
                     return command.call();
 55  
                 } finally {
 56  61
                     runAtExit();
 57  
                 }
 58  
             }
 59  
         };
 60  
     }
 61  
 
 62  
     public static Runnable wrapForAtExit(final Runnable command) {
 63  4
         return new Runnable() {
 64  
             public void run() {
 65  
                 try {
 66  4
                     command.run();
 67  
                 } finally {
 68  4
                     runAtExit();
 69  4
                 }
 70  4
             }
 71  
         };
 72  
     }
 73  
 
 74  
     public static <T> Collection<? extends Callable<T>> wrapForAtExit(Collection<? extends Callable<T>> tasks) {
 75  0
         ArrayList<Callable<T>> newTasks = new ArrayList(tasks.size());
 76  0
         for (Callable<T> task: tasks) {
 77  0
             newTasks.add(wrapForAtExit(task));
 78  
         }
 79  0
         return newTasks;
 80  
     }
 81  
 
 82  
     public static <V> ScheduledFuture<V> schedule(Callable<V> command, long delay, TimeUnit unit) {
 83  65
         return executor.schedule(command, delay, unit);
 84  
     }
 85  
 
 86  
     public static ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit) {
 87  0
         return executor.schedule(command, delay, unit);
 88  
     }
 89  
 
 90  
     public static ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit) {
 91  0
         return executor.scheduleAtFixedRate(command, initialDelay, period, unit);
 92  
     }
 93  
 
 94  
     public static ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long period, TimeUnit unit) {
 95  0
         return executor.scheduleWithFixedDelay(command, initialDelay, period, unit);
 96  
     }
 97  
 
 98  
     public static <T> List<Future<T>> invokeAll(Collection<Callable<T>> tasks) throws InterruptedException {
 99  0
         return executor.invokeAll(tasks);
 100  
     }
 101  
 
 102  
     public static <T> List<Future<T>> invokeAll(Collection<Callable<T>> tasks, long timeout, TimeUnit unit) throws InterruptedException {
 103  0
         return executor.invokeAll(tasks, timeout, unit);
 104  
     }
 105  
 
 106  
     public static <T> T invokeAny(Collection<Callable<T>> tasks) throws InterruptedException, ExecutionException {
 107  0
         return executor.invokeAny(tasks);
 108  
     }
 109  
 
 110  
     public static <T>T invokeAny(Collection<Callable<T>> tasks, long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
 111  0
         return executor.invokeAny(tasks, timeout, unit);
 112  
     }
 113  
 
 114  
     public static <T> Future<T> submit(Callable<T> task) {
 115  0
         return executor.submit(task);
 116  
     }
 117  
 
 118  
     public static Future<?> submit(Runnable task) {
 119  0
         return executor.submit(task);
 120  
     }
 121  
 
 122  
     public static <T> Future<T> submit(Runnable task, T result) {
 123  0
         return executor.submit(task, result);
 124  
     }
 125  
 
 126  
     public static void addAtExit(ThreadSingletonState state) {
 127  706
         LinkedHashSet<ThreadSingletonState> set = atExit.get();
 128  706
         if (set == null) {
 129  334
             set = new LinkedHashSet<ThreadSingletonState>();
 130  334
             atExit.set(set);
 131  
         }
 132  706
         if (set.add(state)) state.start();
 133  706
     }
 134  
 
 135  
     public static void runAtExit() {
 136  396
         LinkedHashSet<ThreadSingletonState> set = atExit.get();
 137  399
         if (set == null) return;
 138  334
         atExit.set(null);
 139  334
         for (ThreadSingletonState state: set) {
 140  706
             state.finish();
 141  
         }
 142  334
     }
 143  
 
 144  
 
 145  
     public static class AtExitExecutor implements Executor {
 146  
         private final Executor real;
 147  
 
 148  2
         protected AtExitExecutor(Executor real) {
 149  2
             this.real = real;
 150  2
         }
 151  
 
 152  
         public void execute(Runnable command) {
 153  0
             real.execute(wrapForAtExit(command));
 154  0
         }
 155  
     }
 156  
 
 157  
     public static class AtExitExecutorService extends AtExitExecutor implements ExecutorService {
 158  
         private final ExecutorService real;
 159  
 
 160  
         protected AtExitExecutorService(ExecutorService real) {
 161  2
             super(real);
 162  2
             this.real = real;
 163  2
         }
 164  
 
 165  
         public boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException {
 166  0
             return real.awaitTermination(timeout, unit);
 167  
         }
 168  
 
 169  
         public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) throws InterruptedException {
 170  0
             return real.invokeAll(wrapForAtExit(tasks));
 171  
         }
 172  
 
 173  
         public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit) throws InterruptedException {
 174  0
             return real.invokeAll(wrapForAtExit(tasks), timeout, unit);
 175  
         }
 176  
 
 177  
         public <T> T invokeAny(Collection<? extends Callable<T>> tasks) throws ExecutionException, InterruptedException {
 178  0
             return real.invokeAny(wrapForAtExit(tasks));
 179  
         }
 180  
 
 181  
         public <T> T invokeAny(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit) throws ExecutionException, InterruptedException, TimeoutException {
 182  0
             return real.invokeAny(wrapForAtExit(tasks), timeout, unit);
 183  
         }
 184  
 
 185  
         public boolean isShutdown() {
 186  0
             return real.isShutdown();
 187  
         }
 188  
 
 189  
         public boolean isTerminated() {
 190  0
             return real.isTerminated();
 191  
         }
 192  
 
 193  
         public void shutdown() {
 194  0
             real.shutdown();
 195  0
         }
 196  
 
 197  
         public List<Runnable> shutdownNow() {
 198  0
             return real.shutdownNow();
 199  
         }
 200  
 
 201  
         public <T> Future<T> submit(Callable<T> task) {
 202  0
             return real.submit(wrapForAtExit(task));
 203  
         }
 204  
 
 205  
         public Future<?> submit(Runnable task) {
 206  4
             return real.submit(wrapForAtExit(task));
 207  
         }
 208  
 
 209  
         public <T> Future<T> submit(Runnable task, T result) {
 210  0
             return real.submit(wrapForAtExit(task), result);
 211  
         }
 212  
     }
 213  
 
 214  0
     public static class AtExitScheduledExecutorService extends AtExitExecutorService implements ScheduledExecutorService {
 215  
         private final ScheduledExecutorService real;
 216  
 
 217  
         protected AtExitScheduledExecutorService(ScheduledExecutorService real) {
 218  2
             super(real);
 219  2
             this.real = real;
 220  2
         }
 221  
 
 222  
         public <V> ScheduledFuture<V> schedule(Callable<V> callable, long delay, TimeUnit unit) {
 223  65
             return real.schedule(wrapForAtExit(callable), delay, unit);
 224  
         }
 225  
 
 226  
         public ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit) {
 227  0
             return real.schedule(wrapForAtExit(command), delay, unit);
 228  
         }
 229  
 
 230  
         public ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit) {
 231  0
             return real.scheduleAtFixedRate(wrapForAtExit(command), initialDelay, period, unit);
 232  
         }
 233  
 
 234  
         public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long period, TimeUnit unit) {
 235  0
             return real.scheduleWithFixedDelay(wrapForAtExit(command), initialDelay, period, unit);
 236  
         }
 237  
     }
 238  
 }