为什么ExecutorService在线程阻塞时继续执行?

时间:2011-07-11 15:07:40

标签: java multithreading executorservice

我正在尝试编写多线程程序的一部分,其中来自固定线程池的每个线程都尝试从队列中获取对象,如果队列为空,则线程等待。

我遇到的问题是程序使用的内存不断增加。

public class Ex3 {

public static LinkedBlockingQueue<Integer> myLBQ = new LinkedBlockingQueue<Integer>(10);

public static void main(String argc[]) throws Exception {
    ExecutorService executor = Executors.newFixedThreadPool(3);
    myLBQ.add(new Integer(1));
    for (;;) {
        executor.execute(new MyHandler(myLBQ));
    }
}
}

class MyHandler implements Runnable {

LinkedBlockingQueue<Integer> myLBQ;

MyHandler(LinkedBlockingQueue<Integer> myLBQ) {
    this.myLBQ = myLBQ;
}

public void run() {
    try {
        myLBQ.take();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}
}

我不明白为什么当线程应该等待项目添加到队列时,executor.execute会继续触发。如何修改我的代码以反映这一点?

2 个答案:

答案 0 :(得分:1)

这会尽可能快地将任务添加到执行程序中。

for (;;) {
    executor.execute(new MyHandler(myLBQ));
}

这将消耗大约每秒200 MB。它与是否有任务无关。

如果您不想这样做,我建议您将循环移动到runnable并仅添加一个。这将导致它永远等待任务。


更好的方法是使用ExecutorService的内置队列来排队任务。

ExecutorService executor = Executors.newFixedThreadPool(3);
final int taskId = 1;
executor.submit(new Runnable() {
    @Override
    public void run() {
        doSomething(taskId);
    }
});

executor.shutdown();

这也是一样,但恕我直言的更简单。

答案 1 :(得分:0)

这是因为您正在创建大量的MyHandler实例并将它们插入执行程序的内部队列中。

无限循环是非常有意义的。