From 495f60836c95faa28955a1183a92b0ecd3b50365 Mon Sep 17 00:00:00 2001 From: Christian Edward Gruber Date: Mon, 28 Jul 2014 06:14:04 -0700 Subject: [PATCH] Open source directExecutor and newDirectExecutorService, deprecate sameThreadExecutor ------------- Created by MOE: http://code.google.com/p/moe-java MOE_MIGRATED_REVID=71699710 --- .../common/util/concurrent/MoreExecutors.java | 68 ++++++++++++++++++- 1 file changed, 67 insertions(+), 1 deletion(-) diff --git a/guava/src/com/google/common/util/concurrent/MoreExecutors.java b/guava/src/com/google/common/util/concurrent/MoreExecutors.java index 4d5022bd9e46..224606b1f432 100644 --- a/guava/src/com/google/common/util/concurrent/MoreExecutors.java +++ b/guava/src/com/google/common/util/concurrent/MoreExecutors.java @@ -263,8 +263,10 @@ private static void useDaemonThreadFactory(ThreadPoolExecutor executor) { * * @since 10.0 (mostly source-compatible since 3.0) + * @deprecated Use {@link #directExecutor()} if you only require an {@link Executor} and + * {@link #newDirectExecutorService()} if you need a {@link ListeningExecutorService}. */ - public static ListeningExecutorService sameThreadExecutor() { + @Deprecated public static ListeningExecutorService sameThreadExecutor() { return new DirectExecutorService(); } @@ -392,6 +394,70 @@ private void endTask() { } } + /** + * Creates an executor service that runs each task in the thread + * that invokes {@code execute/submit}, as in {@link CallerRunsPolicy} This + * applies both to individually submitted tasks and to collections of tasks + * submitted via {@code invokeAll} or {@code invokeAny}. In the latter case, + * tasks will run serially on the calling thread. Tasks are run to + * completion before a {@code Future} is returned to the caller (unless the + * executor has been shutdown). + * + *

Although all tasks are immediately executed in the thread that + * submitted the task, this {@code ExecutorService} imposes a small + * locking overhead on each task submission in order to implement shutdown + * and termination behavior. + * + *

The implementation deviates from the {@code ExecutorService} + * specification with regards to the {@code shutdownNow} method. First, + * "best-effort" with regards to canceling running tasks is implemented + * as "no-effort". No interrupts or other attempts are made to stop + * threads executing tasks. Second, the returned list will always be empty, + * as any submitted task is considered to have started execution. + * This applies also to tasks given to {@code invokeAll} or {@code invokeAny} + * which are pending serial execution, even the subset of the tasks that + * have not yet started execution. It is unclear from the + * {@code ExecutorService} specification if these should be included, and + * it's much easier to implement the interpretation that they not be. + * Finally, a call to {@code shutdown} or {@code shutdownNow} may result + * in concurrent calls to {@code invokeAll/invokeAny} throwing + * RejectedExecutionException, although a subset of the tasks may already + * have been executed. + * + * @since 18.0 (present as MoreExecutors.sameThreadExecutor() since 10.0) + */ + public static ListeningExecutorService newDirectExecutorService() { + return new DirectExecutorService(); + } + + /** + * Returns an {@link Executor} that runs each task in the thread that invokes + * {@link Executor#execute execute}, as in {@link CallerRunsPolicy}. + * + *

This instance is equivalent to:

   {@code
+   *   final class DirectExecutor implements Executor {
+   *     public void execute(Runnable r) {
+   *       r.run();
+   *     }
+   *   }}
+ * + *

This should be preferred to {@link #newDirectExecutorService()} because the implementing the + * {@link ExecutorService} subinterface necessitates significant performance overhead. + * + * @since 18.0 + */ + public static Executor directExecutor() { + return DirectExecutor.INSTANCE; + } + + /** See {@link #directExecutor} for behavioral notes. */ + private enum DirectExecutor implements Executor { + INSTANCE; + @Override public void execute(Runnable command) { + command.run(); + } + } + /** * Creates an {@link ExecutorService} whose {@code submit} and {@code * invokeAll} methods submit {@link ListenableFutureTask} instances to the