Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

java concurrency - keep order between certain tasks

My app receives messages from several users. Messages per user must be executed in order, but otherwise messages can be executed in parallel. How to implement such logic?

E.g. messages arrive in this order: u1:m1 u1:m2 u2:m1 u1:m3 u2:m2. Execution should be parallel like this:

  • thread1: u1:m1 u1:m2 u1:m3
  • thread2: u2:m1 u2:m2

Number of users can be huge, therefore I can't just create a single threaded executor per user.

private ExcutorService executorService = newFixedThreadPool(10);

public void onMessage(String user, String message) {
  // TODO schedule tasks per user in order
  executorService.schedule(() -> processMessage(message));
}
like image 944
nagy.zsolt.hun Avatar asked Dec 22 '25 18:12

nagy.zsolt.hun


1 Answers

You can do it like this:

        //CREATE EXECUTORS
        int numberOfThreads = 10;
        ExecutorService[] executors = new ExecutorService[numberOfThreads];
        for (int i = 0; i < numberOfThreads; i++) {
            executors[i] = Executors.newSingleThreadExecutor();
        }

Then in your method use a specific executor for the user with the help of hashCode and modulo:

public void onMessage(String user, String message) {
    //same user will always get the same executor, hashCode will evenly distribute the load among the executors
    int executorToUse = Math.abs(user.hashCode()) % numberOfThreads; 
    ExecutorService executorService = executors[executorToUse];
    executorService.execute(() -> processMessage(message));
}
like image 66
HPCS Avatar answered Dec 24 '25 06:12

HPCS