can the lazy init be done safely this way? We had a dispute where a colleague was claming for some first threads it could fail and they would see the null value.
public class TestAtomicReference {
static final AtomicReference<String> A = new AtomicReference<>();
public static void main(String[] args) throws Exception {
Callable<Integer> callable = () -> {
lazyInit();
return 0;
};
ExecutorService executorService = Executors.newFixedThreadPool(50);
for (int i = 0; i < 1000; i++) {
A.set(null);
List<Future<Integer>> futures = executorService.invokeAll(Collections.nCopies(50, callable));
futures.forEach(f -> {
try {
f.get();
} catch (Exception ignore) {
}
});
}
executorService.shutdown();
executorService.awaitTermination(10, TimeUnit.SECONDS);
}
private static void lazyInit() {
** if (A.get() == null) {
A.compareAndSet(null, costlyGetValue());
}
**
if (A.get() == null) {
System.out.println("INIT FAILURE!");
}
}
private static String costlyGetValue() {
return "A";
}
}
The separation of get & compareAndSet is there to avoid a costly get every time. This test code never fails... Thanks