### Question:
RefCountResource { public void release() throws RefCountResourceException { synchronized (this) { if (refCount.updateAndGet(i -> i > 0 ? i - 1 : i) == 0 && resource.get() != null) { log.debug("No more References. Cleanup Resource: {}", resource.get()); try { resourceCleanup.accept(resource.getAndSet(null)); } catch (Throwable throwable) { throw new RefCountResourceException(throwable); } } } } RefCountResource(Supplier<? extends T> resourceSupplier,
                            Consumer<? super T> resourceCleanup);   RefCountResource(Supplier<? extends T> resourceSupplier,
                     Consumer<? super T> resourceCleanup,
                     AtomicInteger refCount,
                     AtomicReference<T> resource); T retain(); void release();  }### Answer:
@Test public void releaseShouldCleanupResourceWhenItIsNoLongerUsed() throws Throwable { AtomicInteger refCount = new AtomicInteger(1); RefCountResource resource = new RefCountResource(resourceSupplier, resourceCleanup, refCount, new AtomicReference(new Object())); resource.release(); verify(resourceCleanup).accept(any()); assertEquals(0, refCount.get()); }
@Test public void releaseShouldNotCleanupResourceWhenItIsStillUsed() throws Throwable { AtomicInteger refCount = new AtomicInteger(2); RefCountResource resource = new RefCountResource(resourceSupplier, resourceCleanup, refCount, new AtomicReference(new Object())); resource.release(); verify(resourceCleanup, times(0)).accept(any()); assertEquals(1, refCount.get()); }
@Test public void releaseShouldNotCleanupResourceNonCreatedResource() throws Throwable { AtomicInteger refCount = new AtomicInteger(0); RefCountResource resource = new RefCountResource(resourceSupplier, resourceCleanup, refCount, new AtomicReference(null)); resource.release(); verify(resourceCleanup, times(0)).accept(any()); assertEquals(0, refCount.get()); }