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