Search code examples
javamultithreadingatomicatomicreference

Does the value of AtomicReference will be set lazily if we assign a function to it which returns some array?


I have this piece of code:

AtomicReference<List<String>> atomicStrings = new AtomicReference<>();
atomicStrings.set(someFunc());
Thread.sleep(10000);
System.out.print(String.join(",", atomicStrings.get()); // will this print a,b,c ?

Where

private List<String> someFunc() {
    List<String> list = new ArrayList<>();

    new Thread(() -> {
      try {
        list.add("a");
        Thread.sleep(1000);
        list.add("b");
        Thread.sleep(1000);
        list.add("c");
        Thread.sleep(1000);
      } catch (Exception e) {
        e.printStackTrace();
      }
    }).start();

    return list;
}

Of course this is a very poor example but i tried to mimic my real test case here by adding delays. My question here is that since someFunc() returns the array right away and the array elements are populated in a different thread, but the result we get is stored in an AtomicReference and we don't get the value until later, the delay i am adding in the main function is more than the delay the new thread spawned will take. Will my returned array be populated will all the elements?


Solution

  • You aren't "assigning a function" to it, you're immediately evaluating someFunc and placing the value (a reference to the list) in the AtomicReference.

    The atomic classes have special happens-before constraints, so anything that happens to the list in someFunc is guaranteed to be visible to anyone who retrieves the list from the reference, but your modifications to the list in your spawned thread have no happens-before relationship to the rest of your program. The behavior is undefined, up to and including ConcurrentModificationException.