英文:
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 Runnable
s 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<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.
答案2
得分: 1
使用invokeAll()
非常简单。您需要创建一个Callable
的Collection
:
List<Callable<?>> tasks = ...;
executor.invokeAll(tasks);
invokeAll()
会等待所有Callable
完成。
英文:
It is straightforward to do with invokeAll()
. You need to create a Collection
of Callable
s:
List<Callable<?>> tasks = ...;
executor.invokeAll(tasks);
}
invokeAll()
waits until all Callable
s complete.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论