1. ReentrantLock 可中断
-
ReentrantLock 可以选择在等待锁的时候中断退出,而不必一直等待锁释放
lock.lockInterruptibly();
-
synchronized 中的线程一旦进入阻塞状态,除非锁被释放,否则无法中断退出
2. ReentrantLock 可以设置获取锁的超时时间
在一定时间内如果没有获取锁,就会放弃锁的竞争,而不必一直等待。可以有效避免死锁
/*** Acquires the lock if it is not held by another thread within the given* waiting time and the current thread has not been* {@linkplain Thread#interrupt interrupted}.** <p>Acquires the lock if it is not held by another thread and returns* immediately with the value {@code true}, setting the lock hold count* to one. If this lock has been set to use a fair ordering policy then* an available lock <em>will not</em> be acquired if any other threads* are waiting for the lock. This is in contrast to the {@link #tryLock()}* method. If you want a timed {@code tryLock} that does permit barging on* a fair lock then combine the timed and un-timed forms together:** <pre> {@code* if (lock.tryLock() ||* lock.tryLock(timeout, unit)) {* ...* }}</pre>** <p>If the current thread* already holds this lock then the hold count is incremented by one and* the method returns {@code true}.** <p>If the lock is held by another thread then the* current thread becomes disabled for thread scheduling* purposes and lies dormant until one of three things happens:** <ul>** <li>The lock is acquired by the current thread; or** <li>Some other thread {@linkplain Thread#interrupt interrupts}* the current thread; or** <li>The specified waiting time elapses** </ul>** <p>If the lock is acquired then the value {@code true} is returned and* the lock hold count is set to one.** <p>If the current thread:** <ul>** <li>has its interrupted status set on entry to this method; or** <li>is {@linkplain Thread#interrupt interrupted} while* acquiring the lock,** </ul>* then {@link InterruptedException} is thrown and the current thread's* interrupted status is cleared.** <p>If the specified waiting time elapses then the value {@code false}* is returned. If the time is less than or equal to zero, the method* will not wait at all.** <p>In this implementation, as this method is an explicit* interruption point, preference is given to responding to the* interrupt over normal or reentrant acquisition of the lock, and* over reporting the elapse of the waiting time.** @param timeout the time to wait for the lock* @param unit the time unit of the timeout argument* @return {@code true} if the lock was free and was acquired by the* current thread, or the lock was already held by the current* thread; and {@code false} if the waiting time elapsed before* the lock could be acquired* @throws InterruptedException if the current thread is interrupted* @throws NullPointerException if the time unit is null*/public boolean tryLock(long timeout, TimeUnit unit)throws InterruptedException {return sync.tryAcquireNanos(1, unit.toNanos(timeout));}
3. ReentrantLock 可以设置公平锁
ReentrantLock 可以通过构造方法传参,设置为公平锁,就会按照线程的请求顺序获得锁,先到先得
/*** Creates an instance of {@code ReentrantLock} with the* given fairness policy.** @param fair {@code true} if this lock should use a fair ordering policy*/public ReentrantLock(boolean fair) {sync = fair ? new FairSync() : new NonfairSync();}
4. ReentrantLock 可以尝试获得锁
可以在不阻塞的情况下获得锁,通过 tryLock()
实现
/*** Acquires the lock only if it is not held by another thread at the time* of invocation.** <p>Acquires the lock if it is not held by another thread and* returns immediately with the value {@code true}, setting the* lock hold count to one. Even when this lock has been set to use a* fair ordering policy, a call to {@code tryLock()} <em>will</em>* immediately acquire the lock if it is available, whether or not* other threads are currently waiting for the lock.* This "barging" behavior can be useful in certain* circumstances, even though it breaks fairness. If you want to honor* the fairness setting for this lock, then use* {@link #tryLock(long, TimeUnit) tryLock(0, TimeUnit.SECONDS) }* which is almost equivalent (it also detects interruption).** <p>If the current thread already holds this lock then the hold* count is incremented by one and the method returns {@code true}.** <p>If the lock is held by another thread then this method will return* immediately with the value {@code false}.** @return {@code true} if the lock was free and was acquired by the* current thread, or the lock was already held by the current* thread; and {@code false} otherwise*/public boolean tryLock() {return sync.nonfairTryAcquire(1);}
5. 可以设置条件变量
- ReentrantLock 允许通过 Condition 对象来实现更精细的线程通信和等待唤醒机制。一个 ReentrantLock 可以创建多个Condition 对象,以实现更复杂的线程间同步。
- 与 synchronized 的 wait() 和 notify() 相比,Condition 更灵活,可以指定多个条件队列,避免了 wait 和 notifyAll 带来的无差别唤醒问题。