hminle
hminle

Reputation: 521

Using AtomicInteger with JMH multi-thread?

I am using JMH to test some features of my project. When I try to use it's @GroupThreads with AtomicInteger, I cannot reset the AtomicInteger, it just increases over time. I also tried with if else to check and reset AtomicInteger but cannot. Could you please give me some suggestion for my problem? Thank a lot.

class JMHSample_15_Asymmetric {

  private var counter: AtomicInteger = _

  @Setup
  def up() {
    counter = new AtomicInteger
  }

  @Benchmark
  @Group("g")
  @GroupThreads(3)
  def inc: Int = {
    counter.compareAndSet(10,-1)
    counter.incrementAndGet
  }
  @Benchmark
  @Group("g")
  @GroupThreads(1)
  def get: Int = {
    println("Counter --> "+ counter.get)
    counter.get
  }

}

Upvotes: 1

Views: 402

Answers (1)

Aleksey Shipilev
Aleksey Shipilev

Reputation: 18857

There is an intrinsic race. You might never observe 10 in CAS(10, -1) -- when multiple threads run up increments over 10 -- and so miss the reset action. If you want to have properly synchronized counter modulo N, I would suggest elaborating on this untested sketch:

int countUp() {
  int cur, next;
  do {
    cur = counter.get();
    next = cur < N ? (cur + 1) : 0;
  } while (!counter.compareAndSet(cur, next));
  return next;
}

...or, in Java 8:

int countUp() {
  return counter.updateAndGet(v -> (v < N) ? (v + 1) : 0);
}

Upvotes: 1

Related Questions