Atomicity violations caused by improper usage of ConcurrentHashMap
or ConcurrentLinkedQueue
can result in crashses or incorrect program results. An atomicity violation happens when two instructions are expected and assumed to execute together (“atomically”) but another thread executing on the same data structure in the time between them breaks the atomicity expectation.
1public class ConcurrencyAtomicityViolationNoncompliant {
2
3 private ConcurrentHashMap<String, String> concurrentMap = new ConcurrentHashMap<String, String>();
4
5 public void getValue(String key) {
6 // Noncompliant: the key could be removed from the map between the first call and the second one.
7 if (concurrentMap.containsKey(key)) {
8 String value = concurrentMap.get(key);
9 System.out.println(value.length());
10 }
11 }
12
13 public void deleteValue(String key) {
14 concurrentMap.remove(key);
15 }
16}
1public class ConcurrencyAtomicityViolationCompliant {
2
3 private ConcurrentHashMap<String, String> concurrentMap = new ConcurrentHashMap<String, String>();
4
5 public void getValue(String key) {
6 // Compliant: the value is checked for null before being accessed.
7 String value = concurrentMap.get(key);
8 if (value != null) {
9 System.out.println(value.length());
10 }
11 }
12
13 public void deleteValue(String key) {
14 concurrentMap.remove(key);
15 }
16}