Is there an out-of-the-box thread pool with multiple queues (that ensure serial processing of each queue)?

后端 未结 7 667
星月不相逢
星月不相逢 2020-12-16 11:22

Among all my tasks, I have some that must be processed serially (they can never run concurrently and they must be processed in order).

I achieved that creating a sep

7条回答
  •  时光说笑
    2020-12-16 12:15

    If you maintain a queue for each group, you can pull items off each queue and feed them into a thread pool. The code below won't prioritize any one group, it just pulls them in a round-robin fashion. If you need to add prioritization you should easily be able to. The following code will round-robin 4 groups using two threads (plus the thread managing the queue). You can use another queue mechanism. I typically use LinkedBlockingQueue for situations where I want to wait for items to be placed on the queue by another thread, which probably is not what you want - so I'm polling instead of calling take(). Take is the call that waits.

    private Future group1Future = null;
    private Future group2Future = null;
    private Future group3Future = null;
    private Future group4Future = null;
    private LinkedBlockingQueue group1Queue
            = new LinkedBlockingQueue<>();
    private LinkedBlockingQueue group2Queue
            = new LinkedBlockingQueue<>();
    private LinkedBlockingQueue group3Queue
            = new LinkedBlockingQueue<>();
    private LinkedBlockingQueue group4Queue
            = new LinkedBlockingQueue<>();
    
    private ExecutorService executor = Executors.newFixedThreadPool(2);
    
    
    public void startProcessing() {
        while (true) {
            if (group1Future != null && group1Future.isDone()) {
                if (group1Queue.peek() != null) {
                    group1Future = executor.submit(group1Queue.poll());
                }
            }
            if (group2Future != null && group1Future.isDone()) {
                if (group2Queue.peek() != null) {
                    group2Future = executor.submit(group2Queue.poll());
                }
            }
            if (group3Future != null && group3Future.isDone()) {
                if (group3Queue.peek() != null) {
                    group3Future = executor.submit(group3Queue.poll());
                }
            }
    
            if (group4Future != null && group4Future.isDone()) {
                if (group4Queue.peek() != null) {
                    group4Future = executor.submit(group4Queue.poll());
                }
            }
        }
    }
    

    If a task for that group is not complete, it will skip to the next group. No more than two groups will be processed at a time and no single group will ever run more than one task. The queues will enforce ordered execution.

提交回复
热议问题