2011-01-26 11 views
2

JavaのAtomicIntegerクラスとAtomicLongクラスにはモジュラインクリメントのメソッドがないので驚いています(値を制限した後に値が0になるように)。JavaのAtomicクラスを使用したモジュラインクリメント

私は明らかなものを見逃しているはずです。これを行う最善の方法は何ですか?

たとえば、たとえば、MOD 10

を私はスレッド間の単純なint型を共有したい、と私は、各スレッドがそれをインクリメントすることができるようにしたい私は、同期/ロックを使用するクラスを作成することができますが、より良い、簡単な方法がありますか?

答えて

4

メソッドに​​修飾子またはブロックを追加することは難しいですか?

specific atomic hardware instructionsが現在のCPUで提供されているクラスに基づいており、ロックやより複雑で潜在的に非効率なアルゴリズムに頼らずにモジュラ算術を実装することはできません。マットが提案したもの

+0

説明と実装のためにマイケルに感謝します。 – Mark

11

ちょうどmod 10から読んだときの値は?

public class AtomicWrappingCounter { 
    private final AtomicLong counter = new AtomicLong(); 
    private final int max; 

    public AtomicWrappingCounter(int max) { 
    this.max = max; 
    } 

    public int get() { 
    return (int) (counter.get() % max); 
    } 

    public int incrementAndGet() { 
    return (int) (counter.incrementAndGet() % max); 
    } 
} 

明らかにあなたは、このカウンタ以上Long.MAX_VALUE回をインクリメントする可能性がある場合、あなたはこのアプローチを使用することができませんでしたが、9京は多くの時間がナノ秒あたりの1の割合で(年間292周りをインクリメントすることです! )。

+0

これらのメソッドを同期させる必要はありませんか、ColinD? incrementAndGet()内に1つのスレッドがあり、インクリメントが完了したがモジュロではなく、別のスレッドがget()を呼び出し、モジュロ化されたインクリメントされた値を返します。 – Mark

+1

@マーク:いいえ。モジュロは各スレッドにローカルです。 'AtomicLong'は、' incrementAndGet() 'が呼び出されると、' get() 'を呼び出す他のスレッドが新しい値を参照するようにします。両方のスレッドは、それぞれ独自の値をモジューロし、それぞれが期待される最終結果を見ます。 – ColinD

8

私は最も簡単な方法は、それがのAtomicIntegerの値だ格納する自分に対抗ラッピングを構築することであると思うだろう、

public class AtomicWrappingCounter { 
    private AtomicInteger value; 
    private final int max; 

    public AtomicWrappingCounter(int start, int max) { 
     this.value = new AtomicInteger(start); 
     this.max = max; 
    } 

    public int get() { 
     return value.get(); 
    } 

    /* Simple modification of AtomicInteger.incrementAndGet() */ 
    public int incrementAndGet() { 
     for (;;) { 
      int current = get(); 
      int next = (current + 1) % max; 
      if (value.compareAndSet(current, next)) 
       return next; 
     } 
    } 
} 
のようなもの

はなぜAtomicIntegerはこの自分自身のようなものを提供していませんか?誰が知っているのですが、私は、並行性フレームワークの作者の意図は、独自のより高いレベルの機能をよりうまく作成するために使用できるビルディングブロックを提供することだったと思います。

+0

彼らは本当にフレームワークに 'get'と' compareAndSet'を実装する必要があります。他のすべての方法はそれらの上に構築することができます。 – finnw

+1

賢明ですが、私はヒーブ競争の下では、これは実際には同期より悪いと思われます。 –

+0

@マイケルはなぜあなたは精巧にできますか?それはAtomicInteger自身の行動とは異なるでしょうか? –

1

JavaのAtomicIntegerクラスとAtomicLongクラスにはモジュール化されたメソッドがないことに驚きました。

標準的なクラスには、あらゆる種類の珍しいユースケースをサポートするための「鐘と笛」が含まれていないと、驚かないでください。デザイナーは、含まれているものと含まれていないもののどこかに線を引く必要があります。一般的なユースケースや他の方法ではサポートできないユースケースをサポートする傾向があります。この場合、これらの基準はどちらも適用されません。

関連する問題