### Question:
CloseableThreadLocal { public T get() { return threadLocalMap.computeIfAbsent(Thread.currentThread(), thread -> initialValue.get()); } CloseableThreadLocal(Supplier<T> initialValue, Consumer<T> closeFunction, int poolSize); T get(); void close();  }### Answer:
@Test public void testResourcesAreInitiallyNotClosed() { CloseableThreadLocal<AutoCloseableStub> closeableThreadLocal = new CloseableThreadLocal<>(AutoCloseableStub::new, AutoCloseableStub::close, 1); assertThat(closeableThreadLocal.get().isClosed(), is(false)); }
@Test public void testSubsequentGetsInTheSameThreadGivesBackTheSameObject() { CloseableThreadLocal<AutoCloseableStub> closeableThreadLocal = new CloseableThreadLocal<>(AutoCloseableStub::new, AutoCloseableStub::close, 2); AutoCloseableStub ref1 = closeableThreadLocal.get(); AutoCloseableStub ref2 = closeableThreadLocal.get(); assertThat(ref1, is(ref2)); }
@Test public void testDifferentThreadsHasDifferentInstancesOfTheResource() throws ExecutionException, InterruptedException { CloseableThreadLocal<AutoCloseableStub> closeableThreadLocal = new CloseableThreadLocal<>(AutoCloseableStub::new, AutoCloseableStub::close, 2); AutoCloseableStub asyncInstance = CompletableFuture.supplyAsync(closeableThreadLocal::get).get(); AutoCloseableStub syncInstance = closeableThreadLocal.get(); assertThat(asyncInstance, is(not(syncInstance))); }