183 * create a new thread when needed. Unlike the otherwise |
184 * create a new thread when needed. Unlike the otherwise |
184 * equivalent {@code newFixedThreadPool(1, threadFactory)} the |
185 * equivalent {@code newFixedThreadPool(1, threadFactory)} the |
185 * returned executor is guaranteed not to be reconfigurable to use |
186 * returned executor is guaranteed not to be reconfigurable to use |
186 * additional threads. |
187 * additional threads. |
187 * |
188 * |
188 * @param threadFactory the factory to use when creating new |
189 * @param threadFactory the factory to use when creating new threads |
189 * threads |
|
190 * |
|
191 * @return the newly created single-threaded Executor |
190 * @return the newly created single-threaded Executor |
192 * @throws NullPointerException if threadFactory is null |
191 * @throws NullPointerException if threadFactory is null |
193 */ |
192 */ |
194 public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) { |
193 public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) { |
195 return new FinalizableDelegatedExecutorService |
194 return new FinalizableDelegatedExecutorService |
246 * subsequent tasks.) Tasks are guaranteed to execute |
246 * subsequent tasks.) Tasks are guaranteed to execute |
247 * sequentially, and no more than one task will be active at any |
247 * sequentially, and no more than one task will be active at any |
248 * given time. Unlike the otherwise equivalent |
248 * given time. Unlike the otherwise equivalent |
249 * {@code newScheduledThreadPool(1)} the returned executor is |
249 * {@code newScheduledThreadPool(1)} the returned executor is |
250 * guaranteed not to be reconfigurable to use additional threads. |
250 * guaranteed not to be reconfigurable to use additional threads. |
|
251 * |
251 * @return the newly created scheduled executor |
252 * @return the newly created scheduled executor |
252 */ |
253 */ |
253 public static ScheduledExecutorService newSingleThreadScheduledExecutor() { |
254 public static ScheduledExecutorService newSingleThreadScheduledExecutor() { |
254 return new DelegatedScheduledExecutorService |
255 return new DelegatedScheduledExecutorService |
255 (new ScheduledThreadPoolExecutor(1)); |
256 (new ScheduledThreadPoolExecutor(1)); |
264 * guaranteed to execute sequentially, and no more than one task |
265 * guaranteed to execute sequentially, and no more than one task |
265 * will be active at any given time. Unlike the otherwise |
266 * will be active at any given time. Unlike the otherwise |
266 * equivalent {@code newScheduledThreadPool(1, threadFactory)} |
267 * equivalent {@code newScheduledThreadPool(1, threadFactory)} |
267 * the returned executor is guaranteed not to be reconfigurable to |
268 * the returned executor is guaranteed not to be reconfigurable to |
268 * use additional threads. |
269 * use additional threads. |
269 * @param threadFactory the factory to use when creating new |
270 * |
270 * threads |
271 * @param threadFactory the factory to use when creating new threads |
271 * @return a newly created scheduled executor |
272 * @return the newly created scheduled executor |
272 * @throws NullPointerException if threadFactory is null |
273 * @throws NullPointerException if threadFactory is null |
273 */ |
274 */ |
274 public static ScheduledExecutorService newSingleThreadScheduledExecutor(ThreadFactory threadFactory) { |
275 public static ScheduledExecutorService newSingleThreadScheduledExecutor(ThreadFactory threadFactory) { |
275 return new DelegatedScheduledExecutorService |
276 return new DelegatedScheduledExecutorService |
276 (new ScheduledThreadPoolExecutor(1, threadFactory)); |
277 (new ScheduledThreadPoolExecutor(1, threadFactory)); |
293 * given delay, or to execute periodically. |
294 * given delay, or to execute periodically. |
294 * @param corePoolSize the number of threads to keep in the pool, |
295 * @param corePoolSize the number of threads to keep in the pool, |
295 * even if they are idle |
296 * even if they are idle |
296 * @param threadFactory the factory to use when the executor |
297 * @param threadFactory the factory to use when the executor |
297 * creates a new thread |
298 * creates a new thread |
298 * @return a newly created scheduled thread pool |
299 * @return the newly created scheduled thread pool |
299 * @throws IllegalArgumentException if {@code corePoolSize < 0} |
300 * @throws IllegalArgumentException if {@code corePoolSize < 0} |
300 * @throws NullPointerException if threadFactory is null |
301 * @throws NullPointerException if threadFactory is null |
301 */ |
302 */ |
302 public static ScheduledExecutorService newScheduledThreadPool( |
303 public static ScheduledExecutorService newScheduledThreadPool( |
303 int corePoolSize, ThreadFactory threadFactory) { |
304 int corePoolSize, ThreadFactory threadFactory) { |
676 /** |
677 /** |
677 * A wrapper class that exposes only the ExecutorService methods |
678 * A wrapper class that exposes only the ExecutorService methods |
678 * of an ExecutorService implementation. |
679 * of an ExecutorService implementation. |
679 */ |
680 */ |
680 private static class DelegatedExecutorService |
681 private static class DelegatedExecutorService |
681 extends AbstractExecutorService { |
682 implements ExecutorService { |
682 private final ExecutorService e; |
683 private final ExecutorService e; |
683 DelegatedExecutorService(ExecutorService executor) { e = executor; } |
684 DelegatedExecutorService(ExecutorService executor) { e = executor; } |
684 public void execute(Runnable command) { e.execute(command); } |
685 public void execute(Runnable command) { |
|
686 try { |
|
687 e.execute(command); |
|
688 } finally { reachabilityFence(this); } |
|
689 } |
685 public void shutdown() { e.shutdown(); } |
690 public void shutdown() { e.shutdown(); } |
686 public List<Runnable> shutdownNow() { return e.shutdownNow(); } |
691 public List<Runnable> shutdownNow() { |
687 public boolean isShutdown() { return e.isShutdown(); } |
692 try { |
688 public boolean isTerminated() { return e.isTerminated(); } |
693 return e.shutdownNow(); |
|
694 } finally { reachabilityFence(this); } |
|
695 } |
|
696 public boolean isShutdown() { |
|
697 try { |
|
698 return e.isShutdown(); |
|
699 } finally { reachabilityFence(this); } |
|
700 } |
|
701 public boolean isTerminated() { |
|
702 try { |
|
703 return e.isTerminated(); |
|
704 } finally { reachabilityFence(this); } |
|
705 } |
689 public boolean awaitTermination(long timeout, TimeUnit unit) |
706 public boolean awaitTermination(long timeout, TimeUnit unit) |
690 throws InterruptedException { |
707 throws InterruptedException { |
691 return e.awaitTermination(timeout, unit); |
708 try { |
|
709 return e.awaitTermination(timeout, unit); |
|
710 } finally { reachabilityFence(this); } |
692 } |
711 } |
693 public Future<?> submit(Runnable task) { |
712 public Future<?> submit(Runnable task) { |
694 return e.submit(task); |
713 try { |
|
714 return e.submit(task); |
|
715 } finally { reachabilityFence(this); } |
695 } |
716 } |
696 public <T> Future<T> submit(Callable<T> task) { |
717 public <T> Future<T> submit(Callable<T> task) { |
697 return e.submit(task); |
718 try { |
|
719 return e.submit(task); |
|
720 } finally { reachabilityFence(this); } |
698 } |
721 } |
699 public <T> Future<T> submit(Runnable task, T result) { |
722 public <T> Future<T> submit(Runnable task, T result) { |
700 return e.submit(task, result); |
723 try { |
|
724 return e.submit(task, result); |
|
725 } finally { reachabilityFence(this); } |
701 } |
726 } |
702 public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) |
727 public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) |
703 throws InterruptedException { |
728 throws InterruptedException { |
704 return e.invokeAll(tasks); |
729 try { |
|
730 return e.invokeAll(tasks); |
|
731 } finally { reachabilityFence(this); } |
705 } |
732 } |
706 public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks, |
733 public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks, |
707 long timeout, TimeUnit unit) |
734 long timeout, TimeUnit unit) |
708 throws InterruptedException { |
735 throws InterruptedException { |
709 return e.invokeAll(tasks, timeout, unit); |
736 try { |
|
737 return e.invokeAll(tasks, timeout, unit); |
|
738 } finally { reachabilityFence(this); } |
710 } |
739 } |
711 public <T> T invokeAny(Collection<? extends Callable<T>> tasks) |
740 public <T> T invokeAny(Collection<? extends Callable<T>> tasks) |
712 throws InterruptedException, ExecutionException { |
741 throws InterruptedException, ExecutionException { |
713 return e.invokeAny(tasks); |
742 try { |
|
743 return e.invokeAny(tasks); |
|
744 } finally { reachabilityFence(this); } |
714 } |
745 } |
715 public <T> T invokeAny(Collection<? extends Callable<T>> tasks, |
746 public <T> T invokeAny(Collection<? extends Callable<T>> tasks, |
716 long timeout, TimeUnit unit) |
747 long timeout, TimeUnit unit) |
717 throws InterruptedException, ExecutionException, TimeoutException { |
748 throws InterruptedException, ExecutionException, TimeoutException { |
718 return e.invokeAny(tasks, timeout, unit); |
749 try { |
|
750 return e.invokeAny(tasks, timeout, unit); |
|
751 } finally { reachabilityFence(this); } |
719 } |
752 } |
720 } |
753 } |
721 |
754 |
722 private static class FinalizableDelegatedExecutorService |
755 private static class FinalizableDelegatedExecutorService |
723 extends DelegatedExecutorService { |
756 extends DelegatedExecutorService { |