Class TtlLock

java.lang.Object
cloud.opencode.base.lock.local.TtlLock
All Implemented Interfaces:
Lock<Long>, AutoCloseable

public class TtlLock extends Object implements Lock<Long>
Time-To-Live Lock with Automatic Expiry 带自动过期的生存时间锁

A lock implementation that tracks holding duration and marks the lock as expired after a configured TTL (Time-To-Live). When a lock holder exceeds the TTL, the ownership tracking is cleared, and isExpired() returns true. The actual underlying lock release still depends on the holding thread calling unlock(). This serves as a monitoring and detection mechanism for long-held locks.

一个跟踪持有时间并在配置的 TTL(生存时间)到期后将锁标记为过期的锁实现。 当锁持有者超过 TTL 时,所有权跟踪被清除,isExpired() 返回 true。 底层锁的实际释放仍然取决于持有线程调用 unlock()。 这主要用作长期持有锁的监控和检测机制。

Behavior on TTL Expiry | TTL 过期时的行为:

  • Ownership tracking (ownerThread, acquireTimeNanos) is atomically cleared - 所有权跟踪被原子清除
  • isExpired() returns true, getRemainingTtl() returns ZERO - isExpired() 返回 true,getRemainingTtl() 返回 ZERO
  • The underlying ReentrantLock is NOT force-released (impossible from another thread) - 底层 ReentrantLock 不会被强制释放(无法从其他线程释放)
  • New acquirers still block until the old holder calls unlock() - 新获取者仍然阻塞直到旧持有者调用 unlock()

WARNING | 警告:

TTL expiry is a detection mechanism, not a forced reclamation. Applications should monitor isExpired() and take corrective action (e.g., interrupt the holding thread) rather than relying on automatic release. Set TTL much longer than expected critical section duration.

TTL 过期是一种检测机制,而非强制回收。应用程序应监控 isExpired() 并采取纠正措施(如中断持有线程),而非依赖自动释放。 应将 TTL 设置为远大于预期临界区持续时间的值。

Features | 主要功能:

  • Configurable TTL with automatic expiry detection - 可配置的 TTL 自动过期检测
  • Ownership tracking cleared on expiry - 过期时清除所有权跟踪
  • Remaining TTL query - 剩余 TTL 查询
  • Fair/unfair lock modes - 公平/非公平锁模式
  • Virtual Thread friendly - 虚拟线程友好

Usage Examples | 使用示例:

// Create a TTL lock with 30-second expiry | 创建30秒过期的TTL锁
TtlLock lock = new TtlLock(Duration.ofSeconds(30));

// Use like any other lock | 像其他锁一样使用
try (var guard = lock.lock()) {
    // Critical section - must complete within 30s | 临界区 - 必须在30秒内完成
    processData();
}

// Check remaining TTL | 检查剩余TTL
Duration remaining = lock.getRemainingTtl();
if (remaining.isZero()) {
    log.warn("Lock has expired!");
}

Performance | 性能特性:

  • TTL checks use nanoTime for monotonic timing - TTL检查使用nanoTime单调计时
  • Atomic operations for thread-safe state management - 原子操作保证线程安全状态管理

Security | 安全性:

  • Thread-safe: Yes - 线程安全: 是
  • Virtual Thread friendly: Yes - 虚拟线程友好: 是
  • nanoTime overflow guard: Yes - nanoTime溢出保护: 是
Since:
JDK 25, opencode-base-lock V1.0.3
Author:
Leon Soo www.LeonSoo.com
See Also:
  • Constructor Details

    • TtlLock

      public TtlLock(Duration ttl)
      Creates a TTL lock with the specified time-to-live and unfair ordering 使用指定的生存时间和非公平排序创建TTL锁
      Parameters:
      ttl - the time-to-live duration for lock holding | 锁持有的生存时间
      Throws:
      NullPointerException - if ttl is null | 如果ttl为null则抛出
      IllegalArgumentException - if ttl is non-positive | 如果ttl非正则抛出
    • TtlLock

      public TtlLock(Duration ttl, boolean fair)
      Creates a TTL lock with the specified time-to-live and fairness policy 使用指定的生存时间和公平策略创建TTL锁
      Parameters:
      ttl - the time-to-live duration for lock holding | 锁持有的生存时间
      fair - true for fair ordering, false for unfair | true为公平排序,false为非公平
      Throws:
      NullPointerException - if ttl is null | 如果ttl为null则抛出
      IllegalArgumentException - if ttl is non-positive | 如果ttl非正则抛出
  • Method Details

    • lock

      public LockGuard<Long> lock()
      Description copied from interface: Lock
      Acquires the lock, blocking until available 获取锁,阻塞直到可用

      Examples | 示例:

      try (var guard = lock.lock()) {
          // Use the lock | 使用锁
      } // Automatically released | 自动释放
      
      Specified by:
      lock in interface Lock<Long>
      Returns:
      lock guard for auto-release | 用于自动释放的锁守卫
    • lock

      public LockGuard<Long> lock(Duration timeout)
      Description copied from interface: Lock
      Acquires the lock with timeout 带超时获取锁

      Examples | 示例:

      try (var guard = lock.lock(Duration.ofSeconds(5))) {
          // Use the lock | 使用锁
      }
      
      Specified by:
      lock in interface Lock<Long>
      Parameters:
      timeout - maximum time to wait | 最大等待时间
      Returns:
      lock guard for auto-release | 用于自动释放的锁守卫
    • tryLock

      public boolean tryLock()
      Description copied from interface: Lock
      Tries to acquire the lock immediately without waiting 立即尝试获取锁,不等待

      Examples | 示例:

      if (lock.tryLock()) {
          try {
              // Use the lock | 使用锁
          } finally {
              lock.unlock();
          }
      }
      
      Specified by:
      tryLock in interface Lock<Long>
      Returns:
      true if lock acquired, false otherwise | 获取成功返回true,否则返回false
    • tryLock

      public boolean tryLock(Duration timeout)
      Description copied from interface: Lock
      Tries to acquire the lock with timeout 带超时尝试获取锁
      Specified by:
      tryLock in interface Lock<Long>
      Parameters:
      timeout - maximum time to wait | 最大等待时间
      Returns:
      true if lock acquired, false otherwise | 获取成功返回true,否则返回false
    • lockInterruptibly

      public LockGuard<Long> lockInterruptibly() throws InterruptedException
      Description copied from interface: Lock
      Acquires the lock interruptibly 可中断地获取锁
      Specified by:
      lockInterruptibly in interface Lock<Long>
      Returns:
      lock guard for auto-release | 用于自动释放的锁守卫
      Throws:
      InterruptedException - if interrupted while waiting | 等待时被中断则抛出
    • unlock

      public void unlock()
      Description copied from interface: Lock
      Releases the lock 释放锁

      Should be called in a finally block if not using try-with-resources.

      如果不使用 try-with-resources,应在 finally 块中调用。

      Specified by:
      unlock in interface Lock<Long>
    • isHeldByCurrentThread

      public boolean isHeldByCurrentThread()
      Description copied from interface: Lock
      Checks if lock is held by current thread 检查当前线程是否持有锁
      Specified by:
      isHeldByCurrentThread in interface Lock<Long>
      Returns:
      true if current thread holds the lock | 当前线程持有锁返回true
    • getToken

      public Optional<Long> getToken()
      Description copied from interface: Lock
      Gets the current lock token 获取当前锁令牌
      Specified by:
      getToken in interface Lock<Long>
      Returns:
      lock token, or empty if not locked | 锁令牌,未锁定时返回空
    • isExpired

      public boolean isExpired()
      Checks if the current lock hold has expired beyond the TTL 检查当前锁持有是否已超过TTL过期
      Returns:
      true if the lock is held and has exceeded the TTL | 如果锁被持有且已超过TTL则返回true
    • getRemainingTtl

      public Duration getRemainingTtl()
      Gets the remaining TTL duration for the currently held lock 获取当前持有锁的剩余TTL时间

      Returns Duration.ZERO if the lock is not held or has expired.

      如果锁未被持有或已过期则返回 Duration.ZERO

      Returns:
      the remaining TTL duration | 剩余TTL时间
    • getTtl

      public Duration getTtl()
      Gets the configured TTL duration 获取配置的TTL时间
      Returns:
      the TTL duration | TTL时间