public class PlusPlusOperatorThreadSaftey { @Test public void testThreadSaftey() throws InterruptedException { class IntegerHolder { private volatile int value = 0; private void increase() { value++; } private int getValue() { return value; } } final IntegerHolder integerHolder = new IntegerHolder(); final int numberOfIncreasePerThread = 50; final int numberOfThreads = 100; ExecutorService threadPool = Executors.newFixedThreadPool(numberOfThreads); for (int i = 0; i < numberOfThreads; i++) { threadPool.submit(new Runnable() { public void run() { for (int i = 0; i < numberOfIncreasePerThread; i++) { integerHolder.increase(); } } }); } threadPool.shutdown(); threadPool.awaitTermination(10, TimeUnit.SECONDS); assertEquals(integerHolder.getValue(), numberOfIncreasePerThread * numberOfThreads); } }When running this code on my dual core CPU sometimes the test case passes, and sometimes I get:
java.lang.AssertionError: expected:<4998> but was:<5000>
. Thus, the ++ operator is not atomic and updates can be lost.To fix this you could add a synchronized block, but a better approach is to use an AtomicInteger like this:
class IntegerHolder { private AtomicInteger value = new AtomicInteger(0); private void increase() { value.incrementAndGet(); } private int getValue() { return value.get(); } }
No comments:
Post a Comment