14

多くのコンポーネントを含むタスクの並列実行を実現するために、一連のワーカー スレッドを実行するために使用している fixedThreadPool があります。

すべてのスレッドが終了したら、メソッド (getResult) を使用してそれらの結果 (非常に大きい) を取得し、ファイルに書き込みます。

最終的に、メモリを節約して中間結果を確認できるようにするために、各スレッドが実行を終了したらすぐにその結果をファイルに書き込み、その後メモリを解放するようにします。

通常、run() メソッドの最後にその効果を表すコードを追加します。ただし、このクラスの他の特定のオブジェクトもこれらのスレッドを呼び出しますが、結果をファイルに書き込むことは望ましくありません。代わりに、結果を使用して他の計算を実行し、最終的にファイルに書き込みます。

そこで、ExecutorService を使ってスレッド終了のイベントにコールバック関数を付けられないかと考えていました。そうすれば、そのシナリオですぐに結果を取得してメモリを解放できますが、それらのスレッドが他のシナリオで使用されているときにコードを壊すことはありません。

そのようなことは可能ですか?

4

5 に答える 5

8

Google Guava を使用するオプションがある場合は、次の方法でListenableFutureインターフェイスを利用できます。

  1. ExecutorServiceListeningExecutorServiceに変換しますMoreExecutors.listeningDecorator(existingExecutorService)
  2. submit(Callable<V>)メソッドは、 のサブインターフェイスであるListeningExecutorServiceを返すように絞り込まれました。ListenableFutureFuture
  3. ListenableFutureにはaddListener()メソッドがあり、フューチャが完了したときに実行されるコールバックを登録できます。
于 2014-07-23T01:17:23.543 に答える
4

ExecutorService#submitreturnFutureTask<T>は結果を取得するのに役立ち、ExecutorService#getメソッドは計算が完了するまで実行をブロックします。例 -

ExecutorService executor = Executors.newFixedThreadPool(10);
Future<Long> future = executor.submit(new Callable<Long>(){
       @Override
       public Long call() throws Exception {
           long sum = 0;
           for (long i = 0; i <= 10000000l; i++) {
               sum += i;
           }
           return sum;
       }
});
Long result = future.get();
System.out.println(result);
于 2012-10-29T05:20:59.183 に答える
2

そこで、ExecutorService を使ってスレッド終了のイベントにコールバック関数を付けられないかと考えていました。

直接ではありませんが、これを実現する方法がいくつかあります。頭に浮かぶ最も簡単な方法は、結果を取得Runnableする別の方法でラップすることです。Runnable

したがって、次のようにします。

threadPool.submit(new ResultPrinter(myRunnable));
...

private static class ResultPrinter implements Runnable {
    private final MyRunnable myRunnable;
    public ResultPrinter(MyRunnable myRunnable) {
        this.myRunnable = myRunnable;
    }
    public void run() {
        myRunnable.run();
        Results results = myRunnable.getResults();
        // print results;
    }
}
于 2012-10-29T05:20:29.890 に答える