2
ExecutorService exec = Executors.newFixedThreadPool(8);
List<Future<Object>> results = new ArrayList<Future<Object>>();

// submit tasks
for(int i = 0; i < 8; i++) {
    results.add(exec.submit(new ThreadTask()));
}

...

// stop the pool from accepting new tasks
exec.shutdown();

// wait for results
for(Future<Object> result: results) {
    Object obj = result.get();
}


class ThreadTask implements Callable<Object> {

    public Object call() {
        // execute download
        ...
        return result;
    }
}

上記のコードでは、期待した結果が表示されません。より詳細には、私は android のダウンロード マネージャーを行っています。これらのスレッドは、ファイルをセグメントでダウンロードするためのものです。セグメントごとにダウンロードにかかる時間が異なる場合があるため、そこに問題があると思います。

次に、メソッド内で単純な数値リターンを使用してみました。その後、スレッドが期待どおりの結果を出し始めました。

そのため、解決策として、すべてのスレッドの実行が完了するまで待機するメソッドを実装することを考えました。上記のコードでは、すべてのスレッドが作業を終了するのをどのように待ちますか?. メソッドを使用する必要があると思いますが、そのwait()方法がわかりません。これを理解するのに役立つことを願っています。

御時間ありがとうございます。

4

1 に答える 1

0

ある時点でスレッドのセットが必要な場合は、「バリア」パターンを使用してみてください。

Java SE には実装があります: java.util.concurrent.CyclicBarrier

ドキュメントから : 一連のスレッドが互いに共通のバリア ポイントに到達するのをすべて待機できるようにする同期支援。CyclicBarriers は、相互に時折待機する必要がある固定サイズのスレッドのパーティを含むプログラムで役立ちます。バリアは、待機中のスレッドが解放された後に再利用できるため、サイクリックと呼ばれます。

CyclicBarrier は、オプションの Runnable コマンドをサポートします。これは、パーティの最後のスレッドが到着した後、スレッドが解放される前に、バリア ポイントごとに 1 回実行されます。このバリア アクションは、いずれかの当事者が続行する前に共有状態を更新するのに役立ちます。

http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CyclicBarrier.html

于 2013-09-26T10:40:47.167 に答える