@Test(timeout = 1000L) public void get_memoizes() throws InterruptedException { AtomicInteger provisionCount = new AtomicInteger(); StorageConsumer storageConsumer = new StorageConsumer() { @Override protected StorageComponent tryCompute() { provisionCount.incrementAndGet(); return new InMemoryStorage(); } }; int getCount = 1000; CountDownLatch latch = new CountDownLatch(getCount); ExecutorService exec = Executors.newFixedThreadPool(10); for (int i = 0; i < getCount; i++) { exec.execute(() -> { storageConsumer.get(); latch.countDown(); }); } latch.await(); exec.shutdown(); exec.awaitTermination(1, TimeUnit.SECONDS); assertThat(provisionCount.get()).isEqualTo(1); }
final StorageComponent get() { StorageComponent result = instance; if (result == null) { synchronized (this) { result = instance; if (result == null) { instance = result = tryCompute(); } } } return result; }
StorageConsumer implements Consumer, Component { final StorageComponent get() { StorageComponent result = instance; if (result == null) { synchronized (this) { result = instance; if (result == null) { instance = result = tryCompute(); } } } return result; } }
StorageConsumer implements Consumer, Component { final StorageComponent get() { StorageComponent result = instance; if (result == null) { synchronized (this) { result = instance; if (result == null) { instance = result = tryCompute(); } } } return result; }  }
StorageConsumer implements Consumer, Component { final StorageComponent get() { StorageComponent result = instance; if (result == null) { synchronized (this) { result = instance; if (result == null) { instance = result = tryCompute(); } } } return result; }  @Override final void accept(Iterable<Span> spansSharingId); @Override CheckResult check(); @Override final void close(); }
StorageConsumer implements Consumer, Component { final StorageComponent get() { StorageComponent result = instance; if (result == null) { synchronized (this) { result = instance; if (result == null) { instance = result = tryCompute(); } } } return result; }  @Override final void accept(Iterable<Span> spansSharingId); @Override CheckResult check(); @Override final void close();  }