### Question:
MemoizingSupplier implements Supplier<T> { @Override public T get() { if (value == null) { lock.lock(); try { if (value == null) { value = delegate.get(); } } finally { lock.unlock(); } } return value; } MemoizingSupplier(final Supplier<T> delegate); @Override T get();  }### Answer:
@Test void get() { MemoizingSupplier<String> supplier = new MemoizingSupplier<String>(this::hello); Runnable r = () -> supplier.get(); List<Thread> threads = new ArrayList<>(); for (int i = 0; i < 8; i++) { threads.add(new Thread(r)); } threads.forEach(Thread::start); threads.forEach((Thread t) -> { try { t.join(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } }); Assertions.assertEquals("Hello", supplier.get()); Assertions.assertEquals(1, n); }