Class MoreExecutors


  • @GwtCompatible(emulated=true)
    @Restricted(org.kohsuke.accmod.restrictions.NoExternalUse.class)
    public final class MoreExecutors
    extends Object
    Factory and utility methods for Executor, ExecutorService, and ThreadFactory.
    Since:
    3.0
    Author:
    Eric Fellheimer, Kyle Littlefield, Justin Mahoney
    • Method Detail

      • directExecutor

        public static Executor directExecutor()
        Returns an Executor that runs each task in the thread that invokes execute, as in ThreadPoolExecutor.CallerRunsPolicy.

        This executor is appropriate for tasks that are lightweight and not deeply chained. Inappropriate directExecutor usage can cause problems, and these problems can be difficult to reproduce because they depend on timing. For example:

        • A call like future.transform(function, directExecutor()) may execute the function immediately in the thread that is calling transform. (This specific case happens if the future is already completed.) If transform call was made from a UI thread or other latency-sensitive thread, a heavyweight function can harm responsiveness.
        • If the task will be executed later, consider which thread will trigger the execution -- since that thread will execute the task inline. If the thread is a shared system thread like an RPC network thread, a heavyweight task can stall progress of the whole system or even deadlock it.
        • If many tasks will be triggered by the same event, one heavyweight task may delay other tasks -- even tasks that are not themselves directExecutor tasks.
        • If many such tasks are chained together (such as with future.transform(...).transform(...).transform(...)....), they may overflow the stack. (In simple cases, callers can avoid this by registering all tasks with the same MoreExecutors#newSequentialExecutor wrapper around directExecutor(). More complex cases may require using thread pools or making deeper changes.)
        Additionally, beware of executing tasks with directExecutor while holding a lock. Since the task you submit to the executor (or any other arbitrary work the executor does) may do slow work or acquire other locks, you risk deadlocks.

        This instance is equivalent to:

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

        This should be preferred to #newDirectExecutorService() because implementing the ExecutorService subinterface necessitates significant performance overhead.

        Since:
        18.0