BAEL-1029 - deep20jain@gmail.com - An Introduction to Atomic Variables in Java (#2269)
* Adding test classes for java atomic variables * Updating counter with atomic integer * Adding reason for ignoring test
This commit is contained in:
parent
2ce547d4cd
commit
afa82c0d28
|
@ -0,0 +1,13 @@
|
||||||
|
package com.baeldung.concurrent.atomic;
|
||||||
|
|
||||||
|
public class SafeCounterWithLock {
|
||||||
|
int counter;
|
||||||
|
|
||||||
|
public int getValue() {
|
||||||
|
return counter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void increment() {
|
||||||
|
counter++;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
package com.baeldung.concurrent.atomic;
|
||||||
|
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
|
public class SafeCounterWithoutLock {
|
||||||
|
AtomicInteger counter = new AtomicInteger(0);
|
||||||
|
|
||||||
|
public int getValue() {
|
||||||
|
return counter.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void increment() {
|
||||||
|
while(true) {
|
||||||
|
int existingValue = getValue();
|
||||||
|
int newValue = existingValue + 1;
|
||||||
|
if(counter.compareAndSet(existingValue, newValue)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
package com.baeldung.concurrent.atomic;
|
||||||
|
|
||||||
|
public class UnsafeCounter {
|
||||||
|
int counter;
|
||||||
|
|
||||||
|
public int getValue() {
|
||||||
|
return counter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void increment() {
|
||||||
|
counter++;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,58 @@
|
||||||
|
package com.baeldung.concurrent.atomic;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.stream.IntStream;
|
||||||
|
|
||||||
|
import org.junit.Ignore;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class CounterTest {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This test shows the behaviour of a thread-unsafe class in a multithreaded scenario. We are calling
|
||||||
|
* the increment methods 1000 times from a pool of 3 threads. In most of the cases, the counter will
|
||||||
|
* less than 1000, because of lost updates, however, occasionally it may reach 1000, when no threads
|
||||||
|
* called the method simultaneously. This may cause the build to fail occasionally. Hence excluding this
|
||||||
|
* test by adding Ignore annotation.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
@Ignore
|
||||||
|
public void givenMultiThread_whenUnsafeCounterIncrement() throws InterruptedException {
|
||||||
|
ExecutorService service = Executors.newFixedThreadPool(3);
|
||||||
|
UnsafeCounter unsafeCounter = new UnsafeCounter();
|
||||||
|
|
||||||
|
IntStream.range(0, 1000)
|
||||||
|
.forEach(count -> service.submit(unsafeCounter::increment));
|
||||||
|
service.awaitTermination(100, TimeUnit.MILLISECONDS);
|
||||||
|
|
||||||
|
assertEquals(1000, unsafeCounter.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenMultiThread_whenSafeCounterWithLockIncrement() throws InterruptedException {
|
||||||
|
ExecutorService service = Executors.newFixedThreadPool(3);
|
||||||
|
SafeCounterWithLock safeCounter = new SafeCounterWithLock();
|
||||||
|
|
||||||
|
IntStream.range(0, 1000)
|
||||||
|
.forEach(count -> service.submit(safeCounter::increment));
|
||||||
|
service.awaitTermination(100, TimeUnit.MILLISECONDS);
|
||||||
|
|
||||||
|
assertEquals(1000, safeCounter.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenMultiThread_whenSafeCounterWithoutLockIncrement() throws InterruptedException {
|
||||||
|
ExecutorService service = Executors.newFixedThreadPool(3);
|
||||||
|
SafeCounterWithoutLock safeCounter = new SafeCounterWithoutLock();
|
||||||
|
|
||||||
|
IntStream.range(0, 1000)
|
||||||
|
.forEach(count -> service.submit(safeCounter::increment));
|
||||||
|
service.awaitTermination(100, TimeUnit.MILLISECONDS);
|
||||||
|
|
||||||
|
assertEquals(1000, safeCounter.getValue());
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue