У меня есть несколько воркеров, использующих ArrayBlockingQueue.
Каждый работник берет один объект из очереди, обрабатывает его, и в результате может получить несколько объектов, которые будут помещены в очередь для дальнейшей обработки. Итак, работник = производитель + потребитель.
Worker:
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));
}
}
}
Как остановить рабочих, когда больше нет работы?
Во-первых, я имею в виду периодическую проверку количества элементов в очереди и количества элементов, находящихся в обработке в данный момент. Если оба равны нулю, выполните что-то вроде "shutdownNow()" в ExecutorService. Но я не уверен, что это лучший способ.