手动启动的延迟 ExecutorService

Delayed ExecutorService with manual start

我有一个简单的 ExecutorService(通过 Executors.newSingleThreadExecutor())用于提交 Runnables。但是,我想将这些 Runnables 排队,并且只让 ExecutorService 在我手动通知后执行它们(仅一次)。

N.B。我不是想把它变成一个同步过程——我只是想控制提交的 Runnables

的执行时间

invokeAll()做起来很简单。您需要创建一个 Collection of Callables:

        List<Callable<?>> tasks = ...;
                                   
        executor.invokeAll(tasks);
}

invokeAll() 等待所有 Callable 完成。

既然你用 标记了你的问题,我想你正在考虑以下方向:

ExecutorService es = Executors.newSingleThreadExecutor();

CompletableFuture<Void> trigger = new CompletableFuture<>();

// submit your jobs
trigger.thenRunAsync(aRunnable, es);
trigger.thenRunAsync(anotherRunnable, es);
trigger.thenRunAsync(yetAnotherRunnable, es);

// and later-on
trigger.complete(null);
// now all Runnables will get submitted and executed


// you can use the same construct even after trigger point
// then, the runnable will get submitted immediately

trigger.thenRunAsync(aRunnable, es);

// finally
es.shutdown();

但请注意,这不会维护提交顺序,因为所有操作都被建模为仅取决于触发器。如果你需要保持顺序,你可以使用类似

的东西
CompletableFuture<Void> trigger = new CompletableFuture<>();
CompletableFuture<Void> order = trigger;

// submit your jobs
order = order.thenRunAsync(aRunnable, es);
order = order.thenRunAsync(anotherRunnable, es);
order = order.thenRunAsync(yetAnotherRunnable, es);

// and later-on
trigger.complete(null);

由于只有在上一个作业完成后才会提交下一个作业,因此您必须注意关闭 ExecutorService 的时间。但是您可以使用order.join()等待所有作业完成。

此外,当不同的线程可能以这种方式提交作业时必须小心,因为那时,order 变量的更新必须以线程安全的方式完成。