16

これが私のユースケースです。

レガシー システムは、データベース キュー テーブル QUEUE を更新します。

- QUEUE の内容をチェックするスケジュールされた定期的なジョブが必要です - テーブルに行がある場合は行をロックし、いくつかの作業を行います - QUEUE の行を削除します

前のジョブがまだ実行中の場合は、作業を行うために新しいスレッドが作成されます。同時スレッドの最大数を構成したいと考えています。

私はSpring 3を使用していますが、現在の解決策は次のことです(1ミリ秒のfixedRateを使用して、スレッドを基本的に継続的に実行します)

@Scheduled(fixedRate = 1)
@Async
public void doSchedule() throws InterruptedException {
    log.debug("Start schedule");
    publishWorker.start();
    log.debug("End schedule");
}

<task:executor id="workerExecutor" pool-size="4" />

これにより、すぐに 4 つのスレッドが作成され、スレッドはキューからワークロードを正しく共有しました。ただし、スレッドの完了に時間がかかると、メモリ リークが発生しているようです。

java.util.concurrent.ThreadPoolExecutor @ 0xe097b8f0                              |              80 |   373,410,496 |     89.74%
|- java.util.concurrent.LinkedBlockingQueue @ 0xe097b940                          |           48 |   373,410,136 |     89.74%
|  |- java.util.concurrent.LinkedBlockingQueue$Node @ 0xe25c9d68  

そう

1: @Async と @Scheduled を一緒に使用する必要がありますか?

2:そうでない場合、どのように春を使用して要件を達成できますか?

3: 他のスレッドがビジー状態のときにのみ新しいスレッドを作成するにはどうすればよいですか?

皆さんありがとう!

編集:ジョブのキューが無限に長くなっていたと思います...現在使用しています

    <task:executor id="workerExecutor"
    pool-size="1-4"
    queue-capacity="10" rejection-policy="DISCARD" />

結果はまた報告します

4

2 に答える 2

1
//using a fixedRate of 1 millisecond to get the threads to run basically continuously
@Scheduled(fixedRate = 1)

使用する@Scheduledと、新しいスレッドが作成さdoSchedule れ、指定された fixedRate で 1 ミリ秒でメソッドが呼び出されます。アプリを実行すると、すでに 4 つのスレッドが QUEUE テーブルをめぐって競合しており、デッドロックが発生している可能性があります。

スレッドダンプを採取してデッドロックが発生していないか調査してください。 http://helpx.adobe.com/cq/kb/TakeThreadDump.html

@Async アノテーションはここでは役に立ちません。

これを実装するより良い方法は、 runnable を実装しTaskExecutor、必要な数のスレッドでクラスを渡すことにより、クラスをスレッドとして作成することです。

Spring スレッドと TaskExecutor を使用して、スレッドが終了したことをどのように知ることができますか?

また、同期を適切に処理していないように見える設計を確認してください。前のジョブが実行中で行のロックを保持している場合、作成する次のジョブは引き続きその行を参照し、その特定の行のロックを取得するのを待ちます。

于 2013-10-16T05:19:22.187 に答える