5

私はプログラミングの練習としてparellelクイックソートを実装しています。終了後、ExecutorsのJavaチュートリアルページを読みました。これにより、コードがさらに高速化されるようです。残念ながら、すべてがソートされるまでプログラムが続行されないようにするために、join()に依存していました。現在、私は以下を使用しています:

public static void quicksort(double[] a, int left, int right) {
    if (right <= left) return;
    int i = partition(a, left, right);

    // threads is an AtomicInteger I'm using to make sure I don't
    // spawn a billion threads.
    if(threads.get() < 5){

        // ThreadSort's run method just calls quicksort()
        Future leftThread = e.submit(new ThreadSort(a, left, i-1));
        Future rightThread = e.submit(new ThreadSort(a, i+1, right));

        threads.getAndAdd(2);
        try {
            leftThread.get();
            rightThread.get();
        }
        catch (InterruptedException ex) {}
        catch (ExecutionException ex) {}
    }
    else{
        quicksort(a, left, i-1);
        quicksort(a, i+1, right);
    }
}

これは問題なく機能しているようですが、非再帰的なquicksort()メソッドを呼び出した直後にe.shutdown()を実行すると、RejectedExecutionExceptionsが多数あるため、これは期待どおりに機能していないと思います。

とにかく、私は基本的にleftThread.join()と同じ機能を取得しようとしていますが、Executorを使用しています。私の質問は、

すべてのスレッドが完了するまで待つのに最適な方法ですか?

編集:わかりました。Executorをシャットダウンした後に大量のエラーが発生した理由を理解しました。これは、この関数をループで呼び出していて(実行時間を均等にするため)、新しいExecutorを作成していなかったためです。

4

4 に答える 4

9

どのタイプのエグゼキュータを使用していますか?

ThreadPoolExecutor.awaitTermination()あなたが求めていることを行います(事実上、一括結合操作です)。

合計はさておき、 ThreadPoolExecutor を使用すると、スレッド数などに制限を設定できます...(スレッド数が多くなった場合に行っているように再帰的になるよりも良いかもしれませんが、よくわかりません)。

PS - エグゼキューターによってコードの実行速度が向上するとは思えませんが、コードの読み取りと保守が容易になる可能性があります。スレッド プールを使用すると、この種のアルゴリズムの処理が速くなり、Executor を使用すると、スレッド プールの操作が簡単になります。

于 2009-11-24T03:49:21.833 に答える
4

Executors.newFixedThreadPool最大 n 個のスレッドのプールを作成できる (「if」を取り除く) と、ExecutorService.shutdownメソッドとメソッドを見てExecutorsService.awaitTerminationください。

于 2009-11-24T03:50:54.480 に答える
2

CountDownLatchを使用できます

于 2009-11-24T09:37:29.170 に答える
1

PS - エグゼキューターによってコードの実行速度が向上するとは思えませんが、コードの読み取りと保守が容易になる可能性があります。スレッド プールを使用すると、この種のアルゴリズムの処理が速くなり、Executor を使用すると、スレッド プールの操作が簡単になります。

これは正しくありません。

エグゼキュータは、プールされたスレッドを含む、任意の数の異なる実行システムによって「バックアップ」できます。

ファクトリ クラスを正しく呼び出す必要があります。

さらに、ジョブが消費されるよりも速くキューに送信される状況に対処するためのポリシーを決定する必要もあります。これは、スレッド実行の制限により、最初はメモリ不足にならない可能性があるためです。ジョブは、実行を待つ間、どこかに保存する必要があります。

于 2012-07-05T13:12:09.933 に答える