Delayed ExecutorService with manual start

huangapple go评论63阅读模式
英文:

Delayed ExecutorService with manual start

问题

我有一个简单的ExecutorService(通过Executors.newSingleThreadExecutor()), 我用它来提交Runnable。然而,我想排队这些Runnable,只有在我手动通知它(仅一次)后,ExecutorService才执行它们。

注:我不是要将这变成一个同步过程——我只是想控制提交的Runnable何时执行。

英文:

I have a simple ExecutorService (via Executors.newSingleThreadExecutor()) that I use to submit Runnables to. However, I would like to queue up these Runnables and only let the ExecutorService execute them once I manually notify it (only once).

N.B. I am not trying to make this into a synchronous procedure -- I merely want to control when the execution of the submitted Runnables

答案1

得分: 2

Since you tagged your question with [tag:completable-future], I suppose, you are thinking into the following direction:

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();

But note that this will not maintain the submission order as all actions were modeled as only depending on the trigger. If you need to keep the order, you may use something like

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);

Since this will submit the next job only when the previous has been completed you have to be careful regarding the time of shutting down the ExecutorService. But you can use order.join() to wait for the completion of all jobs.

Further, care must be taken when different threads may submit jobs this way, as then, the update of the order variable must be done in a threadsafe manner.

英文:

Since you tagged your question with [tag:completable-future], I suppose, you are thinking into the following direction:

ExecutorService es = Executors.newSingleThreadExecutor();

CompletableFuture&lt;Void&gt; trigger = new CompletableFuture&lt;&gt;();

// 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();

But note that this will not maintain the submission order as all actions were modeled as only depending on the trigger. If you need to keep the order, you may use something like

CompletableFuture&lt;Void&gt; trigger = new CompletableFuture&lt;&gt;();
CompletableFuture&lt;Void&gt; 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);

Since this will submit the next job only when the previous has been completed you have to be careful regarding the time of shutting down the ExecutorService. But you can use order.join() to wait for the completion of all jobs.

Further, care must be taken when different threads may submit jobs this way, as then, the update of the order variable must be done in a threadsafe manner.

答案2

得分: 1

使用invokeAll()非常简单。您需要创建一个CallableCollection

List<Callable<?>> tasks = ...;

executor.invokeAll(tasks);

invokeAll()会等待所有Callable完成。

英文:

It is straightforward to do with invokeAll(). You need to create a Collection of Callables:

        List&lt;Callable&lt;?&gt;&gt; tasks = ...;
                                   
        executor.invokeAll(tasks);
}

invokeAll() waits until all Callables complete.

huangapple
  • 本文由 发表于 2020年7月28日 13:28:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/63127572.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定