1

ConcurrentLinkedQueue私はマルチコンシューム タスク キューイングに広く使用していましたが、これまでこの問題が発生したことはありませんでした。シーンは次のとおりです。

  1. いくつかのタスクでキューをいっぱいにする
  2. キューからタスクをプールする複数のスレッド (この場合は 2) を実行します。
  3. キューが空でない間、キューからプールしてジョブを実行します。

問題は、私の消費者が最初の要素 TWICE をプールしていることです。混乱を避けるために、重複する要素要素のキューを既にチェックしましたが、何もありません。何が起こっている?理由はわかりませんが、同期queue.poll()してもこの問題は解決しませんでした。これを解決するには?

私のキューポーリング同期ラッパー(以前は必要ありませんでしたが、これはまだ役に立ちません)編集:指摘したように、役に立たなかったが、試してみる必要がありました。正しいアプローチを提案します。

public class MultipleConsumerBlockingQueue<T> extends ConcurrentLinkedQueue<T> {
    private static final long serialVersionUID = 7994932568441881715L;
    private Logger log = LoggerFactory.getLogger(MultipleConsumerBlockingQueue.class);

    @Override
    public synchronized T poll() {
        T item = super.poll();
        return item;
    }

}

消費スレッドの一部

        @Override
        public void run() {
            try {
                AdvancedSearchAgent agent = new AdvancedSearchAgent();
                while ((dp = queue.poll()) != null) {
                    log.info("**** for publication dates: {} - {}", sdf.format(dp.getFromDate()), sdf.format(dp.getToDate()));
                    agent.searchByPublicationDate(dp.getFromDate(), dp.getToDate());
                    log.info("Expected results count {} on {} pages", agent.getResultsCount(), agent.getPagesCount());
                    iterateOverResult(agent, handler);
                }
            } catch (Exception ex) {
                log.error("Unhanded error occured ****. Exiting method *****", ex);
            }

        }

生成された出力:

08:05:15.171 [main] INFO  ****  - Generated 10 date intervals for querying
08:05:15.174 [main] INFO  ****  - Created inner task 1
08:05:15.174 [main] INFO  ****  - Created inner task 2
Czas wykonania= 0 sekund  0 godzin 0 minut 0 sekund
08:05:15.178 [pool-2-thread-1] INFO  **** - **** for publication dates: 01-02-2013 - 03-03-2013
08:05:15.178 [pool-2-thread-2] INFO  **** - ****  for publication dates: 01-02-2013 - 03-03-2013

編集:

これは、キュー内のアイテムのダンプです。重複はありません。

   1# -> Wt 2013-01-01 : Cz 2013-01-31
   2# -> Pt 2013-02-01 : N 2013-03-03
   3# -> Pn 2013-03-04 : Śr 2013-04-03
   4# -> Cz 2013-04-04 : So 2013-05-04
   5# -> N 2013-05-05 : Wt 2013-06-04
   6# -> Śr 2013-06-05 : Pt 2013-07-05
   7# -> So 2013-07-06 : Pn 2013-08-05
   8# -> Wt 2013-08-06 : Cz 2013-09-05
   9# -> Pt 2013-09-06 : N 2013-10-06
  10# -> Pn 2013-10-07 : Pt 2013-10-11
4

3 に答える 3

2

私はよくあるバグを抱えていました - それは Dateformat の NonThreadSafety に関係しています。キューからのポーリングは問題なく、ログのみがエラーで生成されました。 sdfワーカーによって共有される SimpleDateFormat オブジェクトです (最初はシングル スレッドのみであると想定されていたため、誰も気にしませんでした)。スレッドセーフではないため、間違った日付がフォーマットされました。とても悲しいので、以前はそれをキャッチできませんでした。すべてのコメントと指摘に感謝します。

于 2013-10-11T07:28:19.337 に答える
2

ConcurrentLinkedQueue壊れていることはほとんどありません。これは、何百万ものアプリケーションで長年にわたってテストされており、同じ要素を 2 回ポーリングしないことが保証されています。

を定義している場所がわかりませんdp。これがローカル変数でない場合、潜在的な候補を感じます...ローカル変数にしてみて、まだ発生するかどうかを確認してください。

また、これはばかげているように聞こえるかもしれませんが、単一の同一ConcurrentLinkedQueueのオブジェクトからポーリングしていることを確認してください (通常、このようなばかげたことです)。

于 2013-10-11T07:24:37.180 に答える
0

スレッド セーフに Java モニター パターンを使用しないsynchronizedため、メソッドが期待どおりに動作しません。here でConcurrentLinkedQueue説明されているように、別のアプローチを使用します。

于 2013-10-11T06:44:40.643 に答える