### Question:
MemoizingGenerator implements Generator<T> { @Override public T next() { lock.lock(); try { if (!initialized) { value = delegate.next(); initialized = true; } } finally { lock.unlock(); } return value; } MemoizingGenerator(@Nonnull Generator<T> delegate); @Override T next();  }### Answer:
@Test public void shouldReturnSameObject() { Generator<Integer> memoizingGenerator = new MemoizingGenerator<>(Generators.positiveInts); Integer first = memoizingGenerator.next(); assertThat(first, notNullValue()); for (int i = 0; i < 20; i++) { assertThat(memoizingGenerator.next(), sameInstance(first)); } }
@Test public void shouldReturnForMultipleThreads() throws InterruptedException, ExecutionException { final Generator<Integer> memoizingGenerator = new MemoizingGenerator<>(Generators.positiveInts); ExecutorService executorService = newFixedThreadPool(50); Collection<Callable<Integer>> generatorTasks = newArrayList(); generatorTasks.add(new Callable<Integer>() { @Override public Integer call() throws Exception { return memoizingGenerator.next(); } }); try { Set<Integer> singletonSet = newHashSet(); for (Future<Integer> future : executorService.invokeAll(generatorTasks,10, TimeUnit.SECONDS)) { singletonSet.add(future.get()); } assertThat(singletonSet, hasSize(1)); } finally { executorService.shutdown(); } }