I did not find a single working implementation of using an Executor Service with a Blocking Queue. So , I have come with with a working sample. Thoughts?
import java.util.Map;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
class Producer implements Runnable {
protected BlockingQueue queue = null;
public Producer(BlockingQueue queue) {
this.queue = queue;
}
public void run() {
try {
for (int i = 0; i < 10000; i++) {
queue.put(i);
// System.out.println("Producer ID "+Thread.currentThread().getId()+" is adding task : "+i);
}
// poison pill
// System.out.println("Poison number added! "+Thread.currentThread().getId());
queue.put(-1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class Consumer implements Runnable {
protected BlockingQueue queue = null;
ConcurrentHashMap<Integer, Integer> hashmap;
public Consumer(BlockingQueue queue,
ConcurrentHashMap<Integer, Integer> hashmap) {
this.queue = queue;
this.hashmap = hashmap;
}
public void run() {
try {
while (ExecutorTest.isRunning) {
Integer i = (Integer) queue.take();
System.out.println("Consumer " + Thread.currentThread().getId()
+ ": taking Task : " + i);
if (i == -1) {
queue.put(i);
ExecutorTest.isRunning = false;
// System.out.println("Setting isRunning to false : "+Thread.currentThread().getId());
break;
}
hashmap.put(i, i);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class ExecutorTest {
static BlockingQueue<Integer> queue = new LinkedBlockingQueue<Integer>();
static ConcurrentHashMap<Integer, Integer> hashmap = new ConcurrentHashMap<Integer, Integer>();
static volatile boolean isRunning = true;
public static void main(String[] args) {
Producer producer = new Producer(queue);
Consumer consumer = new Consumer(queue, hashmap);
new Thread(producer).start();
ExecutorService executorService = Executors.newFixedThreadPool(4);
executorService.execute(consumer);
executorService.execute(consumer);
executorService.execute(consumer);
executorService.execute(consumer);
// wait for the threads to finish
while (isRunning) {
};
executorService.shutdown();
System.out.println("SHUT DOWN THREAD POOL");
try {
executorService.awaitTermination(10, TimeUnit.SECONDS);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("HASHMAP SIZE : " + hashmap.size());
}
public static void printHashMap() {
for (Map.Entry<Integer, Integer> map : hashmap.entrySet()) {
System.out.println("Entry " + map.getKey() + ":" + map.getValue());
}
}
}
new LinkedBlockingQueue<Integer>()
is redundant, because you can specify it only on the variable side (left). \$\endgroup\$