@Test public void testGraceMode_Timeout() throws Throwable { configureInterruptCycle(false); StateLockManager stateLockManager = new StateLockManager(); StateLockingThread sharedHolderThread = new StateLockingThread(stateLockManager, false); sharedHolderThread.start(); sharedHolderThread.waitUntilStateLockAcquired(); mExpected.expect(TimeoutException.class); stateLockManager .lockExclusive(new StateLockOptions(StateLockOptions.GraceMode.TIMEOUT, 10, 0, 100)); sharedHolderThread.unlockExit(); sharedHolderThread.join(); StateLockingThread exclusiveHolderThread = new StateLockingThread(stateLockManager, true); exclusiveHolderThread.start(); exclusiveHolderThread.waitUntilStateLockAcquired(); mExpected.expect(TimeoutException.class); stateLockManager .lockExclusive(new StateLockOptions(StateLockOptions.GraceMode.TIMEOUT, 10, 0, 100)); exclusiveHolderThread.unlockExit(); exclusiveHolderThread.join(); try (LockResource lr = stateLockManager .lockExclusive(new StateLockOptions(StateLockOptions.GraceMode.TIMEOUT, 10, 0, 100))) { } }
public LockResource lockExclusive(StateLockOptions lockOptions) throws TimeoutException, InterruptedException { LOG.debug("Thread-{} entered lockExclusive().", ThreadUtils.getCurrentThreadIdentifier()); StateLockOptions.GraceMode graceMode = lockOptions.getGraceMode(); boolean graceCycleEntered = false; boolean lockAcquired = false; long deadlineMs = System.currentTimeMillis() + lockOptions.getGraceCycleTimeoutMs(); while (System.currentTimeMillis() < deadlineMs) { if (!graceCycleEntered) { graceCycleEntered = true; LOG.info("Thread-{} entered grace-cycle of try-sleep: {}ms-{}ms for the total of {}ms", ThreadUtils.getCurrentThreadIdentifier(), lockOptions.getGraceCycleTryMs(), lockOptions.getGraceCycleSleepMs(), lockOptions.getGraceCycleTimeoutMs()); } if (mStateLock.writeLock().tryLock(lockOptions.getGraceCycleTryMs(), TimeUnit.MILLISECONDS)) { lockAcquired = true; break; } else { long remainingWaitMs = deadlineMs - System.currentTimeMillis(); if (remainingWaitMs > 0) { Thread.sleep(Math.min(lockOptions.getGraceCycleSleepMs(), remainingWaitMs)); } } } if (lockAcquired) { LOG.info("Thread-{} acquired the lock within grace-cycle.", ThreadUtils.getCurrentThreadIdentifier()); activateInterruptCycle(); } else { if (graceMode == StateLockOptions.GraceMode.TIMEOUT) { throw new TimeoutException( ExceptionMessage.STATE_LOCK_TIMED_OUT.getMessage(lockOptions.getGraceCycleTimeoutMs())); } activateInterruptCycle(); LOG.info("Thread-{} forcing the lock with {} waiters/holders: {}", ThreadUtils.getCurrentThreadIdentifier(), mSharedWaitersAndHolders.size(), mSharedWaitersAndHolders.stream().map((th) -> Long.toString(th.getId())) .collect(Collectors.joining(","))); try { if (!mStateLock.writeLock().tryLock(mForcedDurationMs, TimeUnit.MILLISECONDS)) { throw new TimeoutException(ExceptionMessage.STATE_LOCK_TIMED_OUT .getMessage(lockOptions.getGraceCycleTimeoutMs() + mForcedDurationMs)); } } catch (InterruptedException e) { deactivateInterruptCycle(); throw e; } } return new LockResource(mStateLock.writeLock(), false, false, () -> { deactivateInterruptCycle(); }); }
StateLockManager { public LockResource lockExclusive(StateLockOptions lockOptions) throws TimeoutException, InterruptedException { LOG.debug("Thread-{} entered lockExclusive().", ThreadUtils.getCurrentThreadIdentifier()); StateLockOptions.GraceMode graceMode = lockOptions.getGraceMode(); boolean graceCycleEntered = false; boolean lockAcquired = false; long deadlineMs = System.currentTimeMillis() + lockOptions.getGraceCycleTimeoutMs(); while (System.currentTimeMillis() < deadlineMs) { if (!graceCycleEntered) { graceCycleEntered = true; LOG.info("Thread-{} entered grace-cycle of try-sleep: {}ms-{}ms for the total of {}ms", ThreadUtils.getCurrentThreadIdentifier(), lockOptions.getGraceCycleTryMs(), lockOptions.getGraceCycleSleepMs(), lockOptions.getGraceCycleTimeoutMs()); } if (mStateLock.writeLock().tryLock(lockOptions.getGraceCycleTryMs(), TimeUnit.MILLISECONDS)) { lockAcquired = true; break; } else { long remainingWaitMs = deadlineMs - System.currentTimeMillis(); if (remainingWaitMs > 0) { Thread.sleep(Math.min(lockOptions.getGraceCycleSleepMs(), remainingWaitMs)); } } } if (lockAcquired) { LOG.info("Thread-{} acquired the lock within grace-cycle.", ThreadUtils.getCurrentThreadIdentifier()); activateInterruptCycle(); } else { if (graceMode == StateLockOptions.GraceMode.TIMEOUT) { throw new TimeoutException( ExceptionMessage.STATE_LOCK_TIMED_OUT.getMessage(lockOptions.getGraceCycleTimeoutMs())); } activateInterruptCycle(); LOG.info("Thread-{} forcing the lock with {} waiters/holders: {}", ThreadUtils.getCurrentThreadIdentifier(), mSharedWaitersAndHolders.size(), mSharedWaitersAndHolders.stream().map((th) -> Long.toString(th.getId())) .collect(Collectors.joining(","))); try { if (!mStateLock.writeLock().tryLock(mForcedDurationMs, TimeUnit.MILLISECONDS)) { throw new TimeoutException(ExceptionMessage.STATE_LOCK_TIMED_OUT .getMessage(lockOptions.getGraceCycleTimeoutMs() + mForcedDurationMs)); } } catch (InterruptedException e) { deactivateInterruptCycle(); throw e; } } return new LockResource(mStateLock.writeLock(), false, false, () -> { deactivateInterruptCycle(); }); } }
StateLockManager { public LockResource lockExclusive(StateLockOptions lockOptions) throws TimeoutException, InterruptedException { LOG.debug("Thread-{} entered lockExclusive().", ThreadUtils.getCurrentThreadIdentifier()); StateLockOptions.GraceMode graceMode = lockOptions.getGraceMode(); boolean graceCycleEntered = false; boolean lockAcquired = false; long deadlineMs = System.currentTimeMillis() + lockOptions.getGraceCycleTimeoutMs(); while (System.currentTimeMillis() < deadlineMs) { if (!graceCycleEntered) { graceCycleEntered = true; LOG.info("Thread-{} entered grace-cycle of try-sleep: {}ms-{}ms for the total of {}ms", ThreadUtils.getCurrentThreadIdentifier(), lockOptions.getGraceCycleTryMs(), lockOptions.getGraceCycleSleepMs(), lockOptions.getGraceCycleTimeoutMs()); } if (mStateLock.writeLock().tryLock(lockOptions.getGraceCycleTryMs(), TimeUnit.MILLISECONDS)) { lockAcquired = true; break; } else { long remainingWaitMs = deadlineMs - System.currentTimeMillis(); if (remainingWaitMs > 0) { Thread.sleep(Math.min(lockOptions.getGraceCycleSleepMs(), remainingWaitMs)); } } } if (lockAcquired) { LOG.info("Thread-{} acquired the lock within grace-cycle.", ThreadUtils.getCurrentThreadIdentifier()); activateInterruptCycle(); } else { if (graceMode == StateLockOptions.GraceMode.TIMEOUT) { throw new TimeoutException( ExceptionMessage.STATE_LOCK_TIMED_OUT.getMessage(lockOptions.getGraceCycleTimeoutMs())); } activateInterruptCycle(); LOG.info("Thread-{} forcing the lock with {} waiters/holders: {}", ThreadUtils.getCurrentThreadIdentifier(), mSharedWaitersAndHolders.size(), mSharedWaitersAndHolders.stream().map((th) -> Long.toString(th.getId())) .collect(Collectors.joining(","))); try { if (!mStateLock.writeLock().tryLock(mForcedDurationMs, TimeUnit.MILLISECONDS)) { throw new TimeoutException(ExceptionMessage.STATE_LOCK_TIMED_OUT .getMessage(lockOptions.getGraceCycleTimeoutMs() + mForcedDurationMs)); } } catch (InterruptedException e) { deactivateInterruptCycle(); throw e; } } return new LockResource(mStateLock.writeLock(), false, false, () -> { deactivateInterruptCycle(); }); } StateLockManager(); }
StateLockManager { public LockResource lockExclusive(StateLockOptions lockOptions) throws TimeoutException, InterruptedException { LOG.debug("Thread-{} entered lockExclusive().", ThreadUtils.getCurrentThreadIdentifier()); StateLockOptions.GraceMode graceMode = lockOptions.getGraceMode(); boolean graceCycleEntered = false; boolean lockAcquired = false; long deadlineMs = System.currentTimeMillis() + lockOptions.getGraceCycleTimeoutMs(); while (System.currentTimeMillis() < deadlineMs) { if (!graceCycleEntered) { graceCycleEntered = true; LOG.info("Thread-{} entered grace-cycle of try-sleep: {}ms-{}ms for the total of {}ms", ThreadUtils.getCurrentThreadIdentifier(), lockOptions.getGraceCycleTryMs(), lockOptions.getGraceCycleSleepMs(), lockOptions.getGraceCycleTimeoutMs()); } if (mStateLock.writeLock().tryLock(lockOptions.getGraceCycleTryMs(), TimeUnit.MILLISECONDS)) { lockAcquired = true; break; } else { long remainingWaitMs = deadlineMs - System.currentTimeMillis(); if (remainingWaitMs > 0) { Thread.sleep(Math.min(lockOptions.getGraceCycleSleepMs(), remainingWaitMs)); } } } if (lockAcquired) { LOG.info("Thread-{} acquired the lock within grace-cycle.", ThreadUtils.getCurrentThreadIdentifier()); activateInterruptCycle(); } else { if (graceMode == StateLockOptions.GraceMode.TIMEOUT) { throw new TimeoutException( ExceptionMessage.STATE_LOCK_TIMED_OUT.getMessage(lockOptions.getGraceCycleTimeoutMs())); } activateInterruptCycle(); LOG.info("Thread-{} forcing the lock with {} waiters/holders: {}", ThreadUtils.getCurrentThreadIdentifier(), mSharedWaitersAndHolders.size(), mSharedWaitersAndHolders.stream().map((th) -> Long.toString(th.getId())) .collect(Collectors.joining(","))); try { if (!mStateLock.writeLock().tryLock(mForcedDurationMs, TimeUnit.MILLISECONDS)) { throw new TimeoutException(ExceptionMessage.STATE_LOCK_TIMED_OUT .getMessage(lockOptions.getGraceCycleTimeoutMs() + mForcedDurationMs)); } } catch (InterruptedException e) { deactivateInterruptCycle(); throw e; } } return new LockResource(mStateLock.writeLock(), false, false, () -> { deactivateInterruptCycle(); }); } StateLockManager(); void mastersStartedCallback(); LockResource lockShared(); LockResource lockExclusive(StateLockOptions lockOptions); boolean interruptCycleTicking(); }
StateLockManager { public LockResource lockExclusive(StateLockOptions lockOptions) throws TimeoutException, InterruptedException { LOG.debug("Thread-{} entered lockExclusive().", ThreadUtils.getCurrentThreadIdentifier()); StateLockOptions.GraceMode graceMode = lockOptions.getGraceMode(); boolean graceCycleEntered = false; boolean lockAcquired = false; long deadlineMs = System.currentTimeMillis() + lockOptions.getGraceCycleTimeoutMs(); while (System.currentTimeMillis() < deadlineMs) { if (!graceCycleEntered) { graceCycleEntered = true; LOG.info("Thread-{} entered grace-cycle of try-sleep: {}ms-{}ms for the total of {}ms", ThreadUtils.getCurrentThreadIdentifier(), lockOptions.getGraceCycleTryMs(), lockOptions.getGraceCycleSleepMs(), lockOptions.getGraceCycleTimeoutMs()); } if (mStateLock.writeLock().tryLock(lockOptions.getGraceCycleTryMs(), TimeUnit.MILLISECONDS)) { lockAcquired = true; break; } else { long remainingWaitMs = deadlineMs - System.currentTimeMillis(); if (remainingWaitMs > 0) { Thread.sleep(Math.min(lockOptions.getGraceCycleSleepMs(), remainingWaitMs)); } } } if (lockAcquired) { LOG.info("Thread-{} acquired the lock within grace-cycle.", ThreadUtils.getCurrentThreadIdentifier()); activateInterruptCycle(); } else { if (graceMode == StateLockOptions.GraceMode.TIMEOUT) { throw new TimeoutException( ExceptionMessage.STATE_LOCK_TIMED_OUT.getMessage(lockOptions.getGraceCycleTimeoutMs())); } activateInterruptCycle(); LOG.info("Thread-{} forcing the lock with {} waiters/holders: {}", ThreadUtils.getCurrentThreadIdentifier(), mSharedWaitersAndHolders.size(), mSharedWaitersAndHolders.stream().map((th) -> Long.toString(th.getId())) .collect(Collectors.joining(","))); try { if (!mStateLock.writeLock().tryLock(mForcedDurationMs, TimeUnit.MILLISECONDS)) { throw new TimeoutException(ExceptionMessage.STATE_LOCK_TIMED_OUT .getMessage(lockOptions.getGraceCycleTimeoutMs() + mForcedDurationMs)); } } catch (InterruptedException e) { deactivateInterruptCycle(); throw e; } } return new LockResource(mStateLock.writeLock(), false, false, () -> { deactivateInterruptCycle(); }); } StateLockManager(); void mastersStartedCallback(); LockResource lockShared(); LockResource lockExclusive(StateLockOptions lockOptions); boolean interruptCycleTicking();  }