我正在使用具有阻塞队列的执行程序处理Producer使用者模式。我无法理解为什么这个池没有关闭而主线程终止?
想法是我只有一个生产者和多个消费者(100)
我有一个毒丸项目(-1),当消耗时应触发关闭池。
一切似乎都运转良好,但程序永远不会终止。
这是我的代码:
制作人类:
class Producer implements Runnable {
protected BlockingQueue queue = null;
public Producer(BlockingQueue queue) {
this.queue = queue;
}
public void run() {
try {
for (int i = 0; i < 30000; 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());
//return;
}
hashmap.put(i, i);
//}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
主程序:
公共类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(100);
// wait for the threads to finish
while (isRunning) {
executorService.execute(consumer);
};
try {
executorService.shutdown();
System.out.println("SHUT DOWN THREAD POOL");
while(!executorService.isShutdown()){
}
executorService.awaitTermination(1, TimeUnit.SECONDS);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("HASHMAP SIZE : " + hashmap.size());
try {
queue.put(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void printHashMap() {
for (Map.Entry<Integer, Integer> map : hashmap.entrySet()) {
System.out.println("Entry " + map.getKey() + ":" + map.getValue());
}
}
}
答案 0 :(得分:2)
您可能会在这里产生大量消费者:
while (isRunning) {
executorService.execute(consumer);
};
这些消费者将在queue.take
上阻止而永远不会完成。只有第一个能够取-1的人才会被关闭。
尝试shutdownNow()
,但说实话,我不明白你的while循环的目的,你不应该这样做。