0

私はこのパターンを繰り返していることに気づき、Javaで慣用的なものなのか、それともこの動作を実現するためのより良い方法があるのか​​とよく考えました。

問題:プロデューサー/コンシューマーの設定を考えると、コンシューマーはアイテムのバッチを処理したいので、を使用しますがdrainTo()drainTo()既存のアイテムをポーリングし、アイテムを取得できない可能性があります。これを回避するために、ドレインの前にatake()を付けて、少なくとも1つのアイテムが利用可能です。

特定のデータセットで私が得る問題の1つは、バッチサイズが(1、N、1、N)の間で交互に不規則になることが多いという多くのユースケースです。一般に、これはこの問題を解決するための一般的な方法です。

例:

 ArrayBlockingQueue<Foo> queue;

 function void produce() {
    while(true) {
       queue.put(createFoo());
    }
 }

 function void consumeBatchSpin() {
    while(true) {
       List<Foo> batch = Lists.newLinkedList();
       queue.drainTo(batch);

       doSomething(batch);
       //the problem here is that if nothing is being produced, this loop will spin
    }
 }

 function void consumeBatchTake() {
    while(true) {
       List<Foo> batch = Lists.newLinkedList();
       batch.add(queue.take()); //force at least one item to be there
       queue.drainTo(batch);

       doSomething(batch);
    }
 }
4

1 に答える 1

1

リストに追加して、リスト全体を取得することを検討しましたか。

私は最近ここに投稿しました。ここでコードレビューを受けていますが、私のテストでは堅牢であることが示されています。

基本的に、put を実行すると、新しい要素が現在のリストに追加されます。get を実行すると、リスト全体が取得され、アトミックに新しい空のリストに置き換えられます。

使用する必要はdrainToなく、まったく回転しません。

于 2013-03-04T00:48:49.673 に答える