使用synchronized将会隐式地获取锁,而lock会显示的获取与释放锁。synchronized与lock在使用上存在着些许差别。
Lock API
public interface Lock {
void lock();
void lockInterruptibly() throws InterruptedException;
boolean tryLock();
boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
void unlock();
Condition newCondition();
}
区别
特性 | 描述 |
---|---|
尝试非阻塞地获取锁 | 当前线程尝试获取锁,如果这一时刻锁没有被其他线程获取到,则成功获取并持有锁 |
能被中断地获取锁 | 与synchronized关键字不同,获取到锁的线程能够响应中断,当获取到锁的线程被中断时,中断异常将会被抛出,同时锁会被释放 |
超时获取锁 | 在指定的截止时间之前获取锁,如果截止时间到了仍旧无法获取锁,则返回 |
这里要说的是这些区别都可以从上面提到的Lock Api中找到对应的方法,所以对比联系记忆可能是你需要的。
下面详细说明,首先看尝试非阻塞地获取锁:
/**
* Acquires the lock only if it is free at the time of invocation.
* 只要调用该方法时锁可用就获取锁
*
* <p>Acquires the lock if it is available and returns immediately
* with the value {@code true}.
* If the lock is not available then this method will return
* immediately with the value {@code false}.
* 如果锁可用,获取锁,返回true;如果锁不可用,返回false
*
* <p>A typical usage idiom for this method would be:
* <pre> {@code
* Lock lock = ...;
* if (lock.tryLock()) {
* try {
* // manipulate protected state
* } finally {
* lock.unlock();
* }
* } else {
* // perform alternative actions
* }}</pre>
*
* This usage ensures that the lock is unlocked if it was acquired, and
* doesn't try to unlock if the lock was not acquired.
* 范式用法
*
* @return {@code true} if the lock was acquired and
* {@code false} otherwise
*/
boolean tryLock();
再看能被中断地获取锁,上面对它与synchronized区别的描述其实是不够准确的。先看源码:
/**
* Acquires the lock unless the current thread is
* {@linkplain Thread#interrupt interrupted}.
* 如果当前线程没被中断,则去获取锁
*
* <p>Acquires the lock if it is available and returns immediately.
* 如果锁可用,则获取锁且立即返回
*
* <p>If the lock is not available then the current thread becomes
* disabled for thread scheduling purposes and lies dormant until
* one of two things happens:
* 如果锁不可用,当前线程将不可被调度,直至以下事件发生。
*
* <ul>
* <li>The lock is acquired by the current thread; or 当前线程获取到锁
* <li>Some other thread {@linkplain Thread#interrupt interrupts} the
* current thread, and interruption of lock acquisition is supported.
* </ul>
* 其他线程中断了当前线程,而且获取锁的中断被支持
*
* <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, and interruption of lock acquisition is supported,
* </ul>
* then {@link InterruptedException} is thrown and the current thread's
* interrupted status is cleared.
* 如果线程在进入方法时中断标识位被设置了或者获取锁时被中断了则会抛出中
* 断异常,且标识位被复位。
*
* <p><b>Implementation Considerations</b>
*
* <p>The ability to interrupt a lock acquisition in some
* implementations may not be possible, and if possible may be an
* expensive operation. The programmer should be aware that this
* may be the case. An implementation should document when this is
* the case.
*
* <p>An implementation can favor responding to an interrupt over
* normal method return.
*
* <p>A {@code Lock} implementation may be able to detect
* erroneous use of the lock, such as an invocation that would
* cause deadlock, and may throw an (unchecked) exception in such
* circumstances. The circumstances and the exception type must
* be documented by that {@code Lock} implementation.
*
* @throws InterruptedException if the current thread is
* interrupted while acquiring the lock (and interruption
* of lock acquisition is supported)
*/
void lockInterruptibly() throws InterruptedException;
网友评论