Reputation: 375
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
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