Multithreaded execution where order of finished Work Items is preserved

后端 未结 9 1349
无人共我
无人共我 2021-02-01 08:28

I have a flow of units of work, lets call them \"Work Items\" that are processed sequentially (for now). I\'d like to speed up processing by doing the work multithreaded.

<
9条回答
  •  感情败类
    2021-02-01 09:06

    This is how I solved your problem in a previous project (but with java.util.concurrent):

    (1) WorkItem class does the actual work/processing:

    public class WorkItem implements Callable {
        Object content;
        public WorkItem(Object content) {
            super();
            this.content = content;
        }
    
        public WorkItem call() throws Exception {
            // getContent() + do your processing
            return this;
        }
    }
    

    (2) This class puts Work Items in a queue and initiates processing:

    public class Producer {
        ...
        public Producer() {
            super();
            workerQueue = new ArrayBlockingQueue>(THREADS_TO_USE);
            completionService = new ExecutorCompletionService(Executors.newFixedThreadPool(THREADS_TO_USE));
            workerThread = new Thread(new Worker(workerQueue));
            workerThread.start();
        }
    
        public void send(Object o) throws Exception {
            WorkItem workItem = new WorkItem(o);
            Future future = completionService.submit(workItem);
            workerQueue.put(future);
        }
    }
    

    (3) Once processing is finished the Work Items are dequeued here:

    public class Worker implements Runnable {
        private ArrayBlockingQueue> workerQueue = null;
    
        public Worker(ArrayBlockingQueue> workerQueue) {
            super();
            this.workerQueue = workerQueue;
        }
    
        public void run() {
            while (true) {
                Future fwi = workerQueue.take(); // deqeueue it
                fwi.get(); // wait for it till it has finished processing
            }
        }
    }
    

    (4) This is how you would use the stuff in your code and submit new work:

    public class MainApp {
        public static void main(String[] args) throws Exception {
            Producer p = new Producer();
            for (int i = 0; i < 10000; i++)
                p.send(i);
        }
    }
    

提交回复
热议问题