Berat Postalcioglu
Berat Postalcioglu

Reputation: 375

Java thread safe counter does not work as expected

I have the following Counter class implemented with AtomicInteger. I copied and pasted this class from this article:

public class Counter {
  private final AtomicInteger counter = new AtomicInteger(0);

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

  public void increment() {
      while (true) {
          int existingValue = get();
          int newValue = existingValue + 1;
          if (counter.compareAndSet(existingValue, newValue)) {
              return;
          }
      }
  }
}

I wrote the following test to ensure that it is really a thread safe counter:

@Test
public void counterWorksAsExpected() {
    IntStream.range(0, 100).forEach(j -> {
        int threads = 100;
        Counter counter = new Counter();

        ExecutorService executorService = Executors.newCachedThreadPool();
        IntStream.range(0, threads).forEach(i -> {
            executorService.execute(counter::increment);
        });
        executorService.shutdown();
        assertEquals(threads, counter.get());
    });
}

However at a certain iteration the assertEquals fails.

I want to know that whether my Counter class not thread safe.

Upvotes: 0

Views: 53

Answers (1)

erickson
erickson

Reputation: 269797

You shutdown the executor but you don't wait for the submitted tasks to complete before your assertion. Add a call to awaitTermination() before checking the results.

Upvotes: 3

Related Questions