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