为什么执行者没有关机?

时间:2016-02-15 18:01:08

标签: java multithreading concurrency executorservice threadpoolexecutor

我正在使用具有阻塞队列的执行程序处理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());
    }
}

}

1 个答案:

答案 0 :(得分:2)

您可能会在这里产生大量消费者:

 while (isRunning) {
    executorService.execute(consumer);
 };

这些消费者将在queue.take上阻止而永远不会完成。只有第一个能够取-1的人才会被关闭。

尝试shutdownNow(),但说实话,我不明白你的while循环的目的,你不应该这样做。