4

Java ExecutorServiceフレームワークを使用すると、マネージスレッドプールを使用して実行する多数のタスクを委任できるため、完了するまで一度にN個のタスクをX個のタスクで実行できます。

私の質問は...Nが無限であるか、最初に割り当て/割り当て/定義するのが実用的でないほど大きい数である場合はどうなるでしょうか。

Java(ExecutorService)のスレッドプールの概念を活用して、リソースを使い果たすことなく合理的に送信できるよりも多くのタスクを処理するにはどうすればよいでしょうか。

この回答の目的上、各タスクは自己完結型であり、他のタスクに依存せず、タスクは任意の順序で完了できると想定します。

この問題を攻撃する最初の試みは、ExecutorService Yスレッドに一度にフィードすることでしたが、特定のタスクがいつ完了したかを判断する明確な方法がないため、実行する新しいタスクを送信する方法がないことにすぐに気付きました。

私は自分の「ExecutorService」を書くことができることを知っていますが、Javaフレームワークがすでに提供しているものの恩恵を活用しようとしています。私は一般的に「車輪の再発明をしない」カテゴリーに属しています。なぜなら、私よりも優れた頭脳がすでに私のために投資を行っているからです。

この種の問題を攻撃する方法について洞察を提供してくれる人に事前に感謝します。

4

2 に答える 2

3

a を使用してそれを行うことができますCompletionService。サービスに一連のタスクをシードする 1 つのスレッドを作成し、タスクが完了すると、新しいタスクを追加できます。

簡単な例:

final CompletionService service = new ExecutorCompletionService(Executors.newFixedThreadPool(5));
Runnable taskGenerator = new Runnable() {
    public void run() {
        // Seed the service
        for (int i = 0; i < 100; ++i) {
            service.submit(createNewTask());
        }
        // As tasks complete create new ones
        while (true) {
            Future<Something> result = service.take();
            processResult(result.get());
            service.submit(createNewTask());
        }
    }
};
new Thread(taskGenerator).start();

これは、ThreadPoolExecutor5 つのスレッドを使用してタスクを処理し、手巻きのプロデューサー/コンシューマー スレッドを使用してタスクを生成し、結果を処理します。

明らかに、 よりも少しスマートなものが必要になります。とwhile (true)の適切な実装が必要です。これは、タスクの実行がそれらの生成や結果の処理よりもはるかに遅いことを前提としています。processResultcreateNewTask

うまくいけば、これで正しい軌道に乗ることができます。

于 2012-12-09T01:11:29.943 に答える
0

java.util.concurrent.ArrayBlockingQueue を workQueue として java.util.concurrent.ThreadPoolExecutor を使用します。このようにして、キューのサイズがブロックするよりも多くのタスクを配置しようとします。

  BlockingQueue<Runnable> workQueue=new ArrayBlockingQueue<Runnable>(100);
  ThreadPoolExecutor tpe=new ThreadPoolExecutor(5, 10, 60, TimeUnit.SECONDS, workQueue);

  while (true) {
     tpe.execute(createNewTask());
  }
于 2012-12-09T02:25:18.730 に答える