2016-04-01 13 views
4

AtomicLongsを使用して統計情報を収集しています。一部のユーザーがこれらの競合を見ていて、代わりにLongAdderを使用するように提案しています。しかし、私たちは現在、アトミックで行っているように、最大​​値を計算する方法を参照してくださいません:LongAdderを使用して統計カウンタの最大値を計算する?

AtomicLong _current, _total, _max; 
... 

void add(long delta) 
{ 
    long current = _current.addAndGet(delta); 
    if (delta>0) 
    { 
    _total.addAndGet(delta); 
    long max = _max.get(); 
    while (current > max) 
    { 
     if (_max.compareAndSet(max, current)) 
     break; 
     max = _max.get(); 
    } 
} 

だから私たちはLongAdder_total簡単に十分に取って代わることができると思いますが、我々はうまく動作しません_current.addAndGet(delta)を行うので、 LongAdder、 `_max 'の値に対してcas演算を行うことはできません。

LongAdderまたは同様のスケーラブルなロックフリーコンストラクトに基づいて統計を収集するためのアルゴリズムはありますか?

私が求めているところでは、私たちの統計は、通常、6〜10 AtomicLongsを更新します。とにかく競合が見られたら、ロックをつかんで6〜10ノーマルロングを更新する方がいいでしょうか?

答えて

3

LongAdderではなく、LongAccumulatorここにはnew LongAccumulator(Math::max, Long.MIN_VALUE)が必要です。ここで正しいことをしてください。 LongAdderは、特殊ケースのLongAccumulatorです。

+0

Ahは、 '_max'が' LongAccumulator'に変わることを許しますが、 '_current'に必要なaddAndGetセマンティクスを助けません。ただし、3つのAtomicLongを1 AtomicLong、1 LongAdder、1 LongAccumulatorに置き換えることができます。 – gregw

+1

@ replw:あなたが投稿したメソッドの外でこれらの値を使って実際に何をしているかによって、さらに単純化することができます。あなたが示しているその1つの方法から、3つは常に同じ値を含み、したがって、1つの 'LongAdder'で置き換えることができます... – Holger

+0

@Holger負のデルタを渡すことができるので、3つの値は必ずしも同じではありません。 – gregw

関連する問題