1

let's say I have a spring service

@Service
class SomeClass {
  private ConcurrentHashMap<String, List<SomeItem>> map;
  
  // key is not null, item is not null
  public void addSmth(String key, SomeItem item){
    emptyMap(key);
    List<SomeItem> list = Collections.synchronizedList(new ArrayList<>());
    if(map.containsKey(key)) {
      list = map.get(key);
      list.add(item);
    } else {
      list.add(item);
      map.put(key, list);
    }
  }
  // will remove some entries, check if row is empty and if so: remove the key
  private void emptyMap(key) {
    List<SomeItem> list = map.get(key);
    if(list != null) {
      List<SomeItem> collect = new ArrayList<SomeItem>();
      list.forEach(i -> {
        // basically if element in the list is smaller than one value, I left out the details to make it readable here
        if(i.isSmaller(some_value)) {
           collect.add(i);
        }
      });
      list.removeAll(collect);
      if(list.isEmpty()) {
        map.remove(key);
      }
    }
  }
}

This looks good on first sight but I thought about it and since containsKey and get on the map is not atomic, running this might possibly cause a NullPointerException on list.add(item) since it might be possible that another thread entered map.remove(key) in the emptyMap function when addSmth is invoked concurrently. So my question is:

Is this a race condition in spring boot? I know that Spring uses Tomcat with multiple threads so it should be a problem! And how do I reproduce such an exception (in Tests with Spring). I know I could technically just rewrite it to fix the problem but I'm interested in the reproduction of this! (If it is even an issue)

Many thanks.

zensayyy
  • 38
  • 5

1 Answers1

0

You've covered yourself pretty well with the IF statements, but I suppose you could write a test where you define several Thread executions, and then make each thread go through many loops with random values in a small range, and you'd have a decent chance to catch a race condition.

The problem with these types of code executions is that the race condition might happen only very, very rarely, so it's best to re-write your code if you suspect a problem, rather than hope you don't encounter a race condition.

This post has several references regarding spring boot and multi-threading: Does REST APIs defined in Spring Boot handles multi threading automatically

ESR
  • 46
  • 4