I have several workers that use ArrayBlockingQueue.
Each worker accepts one object from the queue, processes it, and as a result can receive several objects that will be placed in the queue for further processing. So, worker = producer + consumer.
Working:
public class Worker implements Runnable { private BlockingQueue<String> processQueue = null; public Worker(BlockingQueue<String> processQueue) { this.processQueue = processQueue; } public void run() { try { do { String item = this.processQueue.take(); ArrayList<String> resultItems = this.processItem(item); for(String resultItem : resultItems) { this.processQueue.put(resultItem); } } while(true); } catch(Exception) { ... } } private ArrayList<String> processItem(String item) throws Exception { ... } }
Main:
public class Test { public static void main(String[] args) throws Exception { new Test().run(); } private void run() throws Exception { BlockingQueue<String> processQueue = new ArrayBlockingQueue<>(10000); processQueue.put("lalala"); Executor service = Executors.newFixedThreadPool(100); for(int i=0; i<100; ++i) { service.execute(new Worker(processQueue)); } } }
What is the best way to stop workers when there is no more work?
Firstly, I mean, it is periodically checking the number of elements in the queue and the number of elements at the moment. If both are zero, then do something like "shutdownNow ()" in the ExecutorService. But I'm not sure if this is the best way.
source share