LockHandler implements Lock { public void run(@Nonnull Runnable runnable) { DockerCloudUtils.requireNonNull(runnable, "Runnable cannot be null."); lock.lock(); try { runnable.run(); } finally { lock.unlock(); } } private  LockHandler(ReentrantLock lock); void run(@Nonnull Runnable runnable); void runChecked(@Nonnull CheckedRunnable<E> runnable); void runInterruptibly(@Nonnull Runnable runnable); U call(@Nonnull Supplier<U> supplier); U callChecked(CheckedSupplier<U,E> supplier); U callInterruptibly(Supplier<U> supplier); boolean isLocked(); boolean isHeldByCurrentThread(); @Nonnull static LockHandler newReentrantLock(); @Override void lock(); @Override void lockInterruptibly(); @Override boolean tryLock(); @Override boolean tryLock(long time, @NotNull TimeUnit unit); @Override void unlock(); @NotNull @Override Condition newCondition();  }
@Test(timeout = 5000) public void run() { LockHandler lock = LockHandler.newReentrantLock(); ExecutionControl ctrl1 = new ExecutionControl(); runAsync(() -> { assertThat(lock.isLocked()).isFalse(); lock.run(() -> { assertThat(lock.isHeldByCurrentThread()).isTrue(); ctrl1.notifyExecution(); }); }); ctrl1.awaitExecution(); ExecutionControl ctrl2 = new ExecutionControl(); runAsync(() -> { assertThat(lock.isLocked()).isTrue(); assertThat(lock.isHeldByCurrentThread()).isFalse(); lock.run(() -> { assertThat(lock.isHeldByCurrentThread()).isTrue(); ctrl2.notifyExecution(); }); }); waitMillis(500); assertThat(ctrl2.executionStarted).isFalse(); ctrl1.release(); assertThat(Stopwatch.measure(ctrl2::awaitExecution)).isBetween(Duration.ZERO, Duration.ofMillis(100)); ctrl2.release(); }