0

Callables と ThreadPool を使用して、Web サービスを介して (Java API を介して) いくつかのトランザクションを同時に処理しようとしています。

public class CallableTxSender implements Callable<Transaction> {

    private Transaction transaction;
    private Engine engine;

    public CallableTxSender(Transaction transaction, Engine engine) {
        this.transaction = transaction;
        this.engine= engine;
    }

    @Override
    public Transaction call() throws Exception {
        return engine.processTx(transaction);
    }

}

Engine- は、Web サービス呼び出しを行う Api です。

私は、たとえば 50 個のスレッドのプールを作成しています。

ExecutorService executorService = Executors.newFixedThreadPool(50);
List<Transaction> transactions = transactionDao.getPaidTxs();

Engine engine= new Engine();
for (Transaction transaction : transactions) {
    CallableTxSender txSender = new CallableTxSender(transaction, engine);
    executorService.submit(txSender);
}

100 件のトランザクションを処理しようとすると、最初の 20 ~ 30 件のトランザクションで正常に開始され、その後どこかでハングします。API が同時リクエストをサポートしているかどうかはわかりませんが、そうすべきです。

私が確認したいのは、クライアント部分が正常であることです。どう思いますか?

編集:プールサイズを10に減らしましたが、正常に処理されました。コメントのマルコに感謝します。それでも問題は、プールが 10 ではなく 50 の同時タスクでハングするのはなぜですか?

どうもありがとう

4

4 に答える 4

1

あなたが提供したコードに問題はありません。

ハングがどこにあるかを推測する代わりに、jstackまたはでスタック トレースを取得しjvisualvm、ハングしたスレッドの行とスタック トレース、およびそれらが共有しているオブジェクトを見つけます。

于 2012-10-12T10:00:58.427 に答える
1

エグゼキューター サービスに送信されたタスクが他のタスクを送信し、それらの完了を待機すると、スレッド スターベーション デッドロックが発生します。あなたの質問のコードには、それがここで起こっていることを示すものは何もありません。

コードの他の部分がスレッド スタベーション デッドロックを引き起こしている可能性はありますが、他の種類のデッドロックの可能性も考慮する必要があります。


それでも問題は、10 ではなく 50 の同時タスクでプールがハングするのはなぜですか?

確実に言うことはできません。ただし、考えられる説明の 1 つは、同時により多くのタスクを実行すると、特定のロック シナリオが発生する可能性が高くなることです。(類推は誕生日のパラドックスと一緒です...)

必然的に、プール サイズを小さくするとデッドロックの可能性が大幅に減少しますが、問題が完全に解消されたかどうかはわかりません。

于 2012-10-12T10:34:39.240 に答える
0

java.util.concurrent のThreadPoolExecutor実装は、スレッド プール サイズ、workQueue サイズ、およびその他のさまざまな拡張フックを調整するのに役立ちます。キュー サイズと最大プール サイズは、互いにトレードオフされる場合があります。新しいタスクは、すべての corePoolSize スレッドがビジー状態になると workQueue で待機するか、最大プール サイズまで新しいスレッドを作成します。両方の workQueue がいっぱいで、最大プール スレッドが使用中の場合、Executor に送信された新しいタスクは拒否され、タスク拒否ポリシーの 1 つが有効になります。workQueue のサイズが大きい場合、タスクが互いに独立していることが重要です。

于 2012-10-12T13:18:16.110 に答える
0

トランザクションが相互に依存していなければ、コードは問題ありません。確認するには、newFixedThreadPool の代わりに newCachedThreadPool を使用してください。

于 2012-10-12T10:07:26.663 に答える