LockManagerImpl implements LockManager { @Override public void assertNotLocked(final ILockKey context) throws LockException { Optional<ILock> stored = storage.read( storeProvider -> storeProvider.getLockStore().fetchLock(context)); if (stored.isPresent()) { throw new LockException(String.format( "Unable to perform operation for %s due to active lock held", formatLockKey(context))); } } @Inject  LockManagerImpl(Storage storage, Clock clock, UUIDGenerator tokenGenerator); @Override ILock acquireLock(final ILockKey lockKey, final String user); @Override void releaseLock(final ILock lock); @Override void assertNotLocked(final ILockKey context); @Override Iterable<ILock> getLocks();  }
@Test public void testNoDeadlock() throws Exception { final StorageTestUtil storageUtil = new StorageTestUtil(this); expect(storageUtil.storeProvider.getLockStore()).andReturn(storageUtil.lockStore).atLeastOnce(); expect(storageUtil.lockStore.fetchLock(LOCK_KEY)) .andReturn(Optional.empty()) .atLeastOnce(); final CountDownLatch reads = new CountDownLatch(2); EasyMock.makeThreadSafe(storageUtil.storage, false); expect(storageUtil.storage.read(EasyMock.anyObject())) .andAnswer(() -> { @SuppressWarnings("unchecked") Work<?, ?> work = (Work<?, ?>) EasyMock.getCurrentArguments()[0]; Object result = work.apply(storageUtil.storeProvider); reads.countDown(); reads.await(); return result; }).atLeastOnce(); lockManager = new LockManagerImpl(storageUtil.storage, clock, tokenGenerator); control.replay(); new ThreadFactoryBuilder() .setDaemon(true) .setNameFormat("LockRead-%s") .build() .newThread(() -> { try { lockManager.assertNotLocked(LOCK_KEY); } catch (LockException e) { throw Throwables.propagate(e); } }) .start(); lockManager.assertNotLocked(LOCK_KEY); }