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 が起動し続ける理由がわかりません。これを反映するようにコードを変更するにはどうすればよいですか?

4

2 に答える 2

1

これにより、タスクがエグゼキューターにできるだけ早く追加されます。

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

これにより、毎秒約 200 MB が消費されます。実行するタスクがあるかどうかとは関係ありません。

これをしたくない場合は、ループをランナブルに移動して、1 つだけ追加することをお勧めします。これにより、タスクを永久に待機することになります。


より良い方法は、ExecutorService の組み込みキューを使用してタスクをキューに入れることです。

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

executor.shutdown();

これは同じことを行いますが、はるかに単純です。

于 2011-07-11T15:11:57.540 に答える
0

これは、膨大な数の MyHandler インスタンスを作成し、それらをエグゼキューターの内部キューに挿入しているためです。

その無限の for ループはかなり意地悪です。

于 2011-07-11T15:11:11.623 に答える