ThreadPoolExecutor avoid concurrent processing for same ID
I get tasks for my customers. Each customer has an ID. I want that all tasks from one customer (ie. same ID) are processed sequentially, and not concurrently. But, it is fully OK to process two different customers concurrently.
The processing is done by a ThreadPoolExecutor with many threads. How should I modify the Queue or the ThreadPoolExecutor so that whenever a task is submitted, it is first checked whether for the same ID another task is already running, and in this case, it is put in some waiting state.
Note: jkeylockmanager (https://code.google.com/p/jkeylockmanager/ ) goes in the right direction, but it just manages locks per ID, and not the thread selection.
Consider keeping a threadsafe queue of customer ID's who have made requests. Then, submit only the customer ID to the thread pool. For example:
DoAllCustomerTasks customer1 = new DoAllCustomerTasks(1); DoAllCustomerTasks customer2 = new DoAllCustomerTasks(2); threadPool.submit(customer1); threadPool.submit(customer2);
Then, DoAllCustomerTasks would implement Runnable and it would be responsible for finding and executing all tasks associated with the customerID it was constructed with.
Probably, there is better solution, but what if: Instead of using ThreadPoolExecutor, use array of N single thread executors. To process request with id=someId
executors[someId % N].submit(task);
We take division reminder as executor index to ensure that requests with same id will be processed by same thread