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

发布于 2024-11-19 14:39:55 字数 829 浏览 1 评论 0原文

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

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

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 不断触发。如何修改我的代码以反映这一点?

I am trying to write a part of a multithreaded program where each thread from a fixed thread pool tries to fetch an object from a Queue and if the Queue is empty the thread waits.

The problem I am experiencing is that the memory used by the program keeps increasing.

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();
    }
}
}

I don't understand why the executor.execute keeps firing when the threads should be waiting for an item to be added to the Queue. How do I modify my code to reflect this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

扭转时空 2024-11-26 14:39:55

这会尽快向执行器添加任务。

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

这将消耗大约 200 MB 每秒。这与是否有任务要执行没有任何关系。

如果您不想这样做,我建议您将循环移至可运行状态并仅添加一个。这将导致它永远等待任务。


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

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

executor.shutdown();

这做同样的事情,但恕我直言,更简单。

This adds tasks to the executor as fast as it can.

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

This will consume about 200 MB per second. It doesn't have anything to do with whether there are tasks to perform or not.

If you don't want to do this I suggest you move the loop to the runnable and add only one. This will cause it to wait for tasks forever.


A better approach is to use the ExecutorService's builtin queue to queue tasks.

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

executor.shutdown();

This does the same thing, but is much simpler IMHO.

夏见 2024-11-26 14:39:55

这是因为您正在创建无数个 MyHandler 实例并将它们插入执行器的内部队列中。

那个无限循环是相当卑鄙的。

it's because you're creating a gazillion instances of MyHandler and inserting them in the internal queue of the executor.

That infinite for loop is quite mean.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文