如何在Java中实现并发循环自动收报机(计数器)?

she*_*eki 13 java concurrency counter atomicity

我想用Java实现一个循环计数器.每个请求的计数器应该(原子地)递增,并且在达到上限时应该翻转到0.

实现这一点的最佳方法是什么,是否有任何现有的实现?

NPE*_*NPE 20

很容易实现这样的计数器AtomicInteger:

public class CyclicCounter {

    private final int maxVal;
    private final AtomicInteger ai = new AtomicInteger(0);

    public CyclicCounter(int maxVal) {
        this.maxVal = maxVal;
    }

    public int cyclicallyIncrementAndGet() {
        int curVal, newVal;
        do {
          curVal = this.ai.get();
          newVal = (curVal + 1) % this.maxVal;
        } while (!this.ai.compareAndSet(curVal, newVal));
        return newVal;
    }

}
Run Code Online (Sandbox Code Playgroud)


igo*_*.zh 8

使用Java 8

public class CyclicCounter {

    private final int maxVal;
    private final AtomicInteger counter = new AtomicInteger(0);

    public CyclicCounter(int maxVal) {
      this.maxVal = maxVal;
    }

    return counter.accumulateAndGet(1, (index, inc) -> {
        return ++index >= maxVal ? 0 : index;
    });      
Run Code Online (Sandbox Code Playgroud)

}


Joe*_*ney 7

如果你是担心使用或者CAS或争synchronized,那么你可以考虑一些更复杂的,如建议JSR 166E LongAdder(,的javadoc).

这是一个简单的计数器,在多线程访问时争用率很低.您可以将其包装为公开(当前值mod最大值).也就是说,根本不存储包装的值.