Design pattern to guarantee only one Runnable obje

2019-06-27 03:48发布

问题:

Suppose I have an ordered list of Runnable objects that are to be executed by ExecutorService. My Runnable objects have a userID filed - let's say I have about 20 different userId-s and 10 is the number of threads in the pool (ExecutorService object).

What is a general design pattern to ensure that at most 1 Runnable object of particular group is being executed in one of threads at one time? (The goal is that all Runnable from one id group should be executed cronologically and synchronously).

回答1:

You could create queues for each group and when a task terminates you read the corresponding queue and submit the next task if needed.

For that you somehow need to identify when a Runnable terminates. With the standard JDK classes you cannot really do that in a simple way but using the Guava library you can wrap your ExecutorService into a ListeningExecutorService. If you submit a task through this wrapper it will return you a ListenableFuture instead of the plain Java Future. A ListenableFuture will let you register callbacks that will be executed when the task terminates. In these callbacks you can check your queues and submit the next tasks in the same group.



回答2:

For each Id, you need a lightweight SerialExecutor like one described in JavaDocs of Executor. That implementation is not optimal - for each input task, it creates additional service Runnable. Opimized version can be found at https://github.com/rfqu/CodeSamples/blob/master/src/simpleactor/SerialExecutor.java, where SerialExecutor serves as intermediate Runnable and resubmits itself when it is idle and a new task appears.