@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();
}