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?
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
.