4

私は...タイトルをより適切に表現する方法が本当にわかりません。しかし、基本的に、私が持っているのは、これらすべてのスレッドが忙しく動作しているスレッド プールです。配属された順番で結果を報告してもらいたいが、同時にバッチで作業したい。説明すると、例は次のようになります

ExecutorService exec = Executors.newFixedThreadPool(8);

class MyCallable implements Callable<byte[]> {
    private final int threadnumber;

    MyCallable(int threadnumber){
        this.threadnumber = threadnumber;
    }

    public byte[] call() {
        //does something
    }
}
List<Callable<byte[]>> callables = new ArrayList<Callable<byte[]>>();

for(int i=1; i<=20; i++) {
    callables.add(new MyCallable(i));
}
try {
    List<Future<byte[]>> results = exec.invokeAll(callables);
    for(Future<byte[]> result: results) {
            System.out.write(result.get(), 0, result.get().length);
    }

基本的に、プール スレッドには 8 つのスレッドがあり、最終的に 20 のタスクがあります (これらは単なる例です)。私が正しく理解している場合、これが現在機能する方法は、20 個のタスクすべてが完了するまで待機してから、それらを順番に出力することです (1 から 20 まで)。このプログラムが行うことになっているのは、バイトの連続ストリームを出力することです (スレッドによって処理され、順序をそのまま維持する必要があるため、future インターフェイスを使用しました)。20 個のタスクがすべて完了するまで待ってもかまいませんが、とにかく、スレッドが進むにつれて順番に出力されるようにする必要があります。

方法がない場合や、invokeAll の仕組みを完全に誤解している場合は、その説明も歓迎します。事前にたくさんありがとう!Executor について知ったばかりなので、少し混乱しています。

ランダムな補遺ですが、callable からバイト配列を返すことはできますか?

4

2 に答える 2

6

invokeAll()すべての結果が計算されるまで待ってから戻ります。

代わりにループを使用し、submit()それらを1つずつ使用します。このメソッドは、保留中の結果を含むFutureをすぐに返します。

...
for(int i=1; i<=20; i++) {
    results.add(exec.submit(new MyCallable(i))); 
}
try {
    for(Future<Integer> result: results) {
            System.out.write(result.get(), 0, result.get().length);
    }
}
...
于 2012-10-28T20:03:02.730 に答える
2

invokeAll を使用することもできます。

 List<Future<byte[]>> results = exec.invokeAll(callables); 

将来のオブジェクト リストを返します。

ThreadPoll はランダムな順序でタスクを実行します。タスクの実行順序は制御できません。

将来のオブジェクト

  1. ThreadPool にサブミットされたタスクの参照です。

  2. メソッドget()があります。ブロッキング呼び出しメソッドです。get() メソッドを呼び出すと、呼び出しはタスクが完了するまで待機します。

タスクの送信順序を確認する方法

結果の順序は callable の順序と同じです。スレッド プールでさえ、同じ順序で取得できる別の順序で実行されます。

例の場合。

3 つのタスク 1、2、3

1 & 3 --> 完了。

2 ------> 実行に時間がかかります。

invokeAll メソッドを呼び出すと、同じ順序で Future の List が返されます。

タスク 1 : Future#get メソッドは既に完了しているため、結果を返します

タスク 2 : Future#get メソッドは、タスクが完了するまで待機します。

3 番目のタスクが完了しても、反復は 2 番目のタスクが完了するまで待機します。3 番目のスレッドからは結果が得られません。

于 2014-08-15T18:39:07.960 に答える