Lock是由Doug Lea编写,并且发布与JDK1.5,提供了不同于语法synchronized的加锁方式。以下注释是对接口Lock的说明,部分进行了中文翻译。
/**
* {@code Lock} implementations provide more extensive locking
* operations than can be obtained using {@code synchronized} methods
* and statements. They allow more flexible structuring, may have
* quite different properties, and may support multiple associated
* {@link Condition} objects.
* Lock implementations 为同步方法和语句提供了更广泛的锁操作。它们允许更
* 灵活的结构,可能有大量不同的配置,能支持多个关联对象。
*
*
A lock is a tool for controlling access to a shared resource by
* multiple threads. Commonly, a lock provides exclusive access to a
* shared resource: only one thread at a time can acquire the lock and
* all access to the shared resource requires that the lock be
* acquired first. However, some locks may allow concurrent access to
* a shared resource, such as the read lock of a {@link ReadWriteLock}.
* 锁是多线程控制访问共享资源的工具。一般的,锁提供共享资源的独占访问;同一时刻
* 只有一个线程能够获取锁。然而,一些锁可能允许同时访问共享资源,例如读锁。
*
*
The use of {@code synchronized} methods or statements provides
* access to the implicit monitor lock associated with every object, but
* forces all lock acquisition and release to occur in a block-structured way:
* when multiple locks are acquired they must be released in the opposite
* order, and all locks must be released in the same lexical scope in which
* they were acquired.
* 同步方法或语句使用synchronized语法访问与每个对象关联的隐式监视器锁,但是强制所有锁
* 获取和释放通过block-structured way;当获取的多个锁必须已相反的顺序释放,同时所有锁
* 的释放必须和获取在同一个语法空间。
*
*
While the scoping mechanism for {@code synchronized} methods
* and statements makes it much easier to program with monitor locks,
* and helps avoid many common programming errors involving locks,
* there are occasions where you need to work with locks in a more
* flexible way. For example, some algorithms for traversing
* concurrently accessed data structures require the use of
* "hand-over-hand" or "chain locking": you
* acquire the lock of node A, then node B, then release A and acquire
* C, then release B and acquire D and so on. Implementations of the
* {@code Lock} interface enable the use of such techniques by
* allowing a lock to be acquired and released in different scopes,
* and allowing multiple locks to be acquired and released in any
* order.
* 然而作用域机制对于synchronized方法和语句更容易使用监视器锁编程,助其避免使用锁的一些
* 常见错误,但有些场合需要已一种更灵活的方式使用锁。例如,一些遍历算法并发访问数据结构
* 时使用hand-over-hand和chain locking。先获取Node A的锁,然后获取Node B的锁,之后释放A
* 的锁,获取C的锁,释放B的锁,获取D的锁等等。Lock接口的实现允许获取和释放锁在不同的作用
* 域,允许已不同的顺序获取和释放多个锁。
*
*
With this increased flexibility comes additional
* responsibility. The absence of block-structured locking removes the
* automatic release of locks that occurs with {@code synchronized}
* methods and statements. In most cases, the following idiom
* should be used:
*
*
{@code
* Lock l = ...;
* l.lock();
* try {
* // access the resource protected by this lock
* } finally {
* l.unlock();
* }}
*
* When locking and unlocking occur in different scopes, care must be
* taken to ensure that all code that is executed while the lock is
* held is protected by try-finally or try-catch to ensure that the
* lock is released when necessary.
*
*
{@code Lock} implementations provide additional functionality
* over the use of {@code synchronized} methods and statements by
* providing a non-blocking attempt to acquire a lock ({@link
* #tryLock()}), an attempt to acquire the lock that can be
* interrupted ({@link #lockInterruptibly}, and an attempt to acquire
* the lock that can timeout ({@link #tryLock(long, TimeUnit)}).
*
*
A {@code Lock} class can also provide behavior and semantics
* that is quite different from that of the implicit monitor lock,
* such as guaranteed ordering, non-reentrant usage, or deadlock
* detection. If an implementation provides such specialized semantics
* then the implementation must document those semantics.
*
*
Note that {@code Lock} instances are just normal objects and can
* themselves be used as the target in a {@code synchronized} statement.
* Acquiring the
* monitor lock of a {@code Lock} instance has no specified relationship
* with invoking any of the {@link #lock} methods of that instance.
* It is recommended that to avoid confusion you never use {@code Lock}
* instances in this way, except within their own implementation.
*
*
Except where noted, passing a {@code null} value for any
* parameter will result in a {@link NullPointerException} being
* thrown.
*
*
Memory Synchronization
*
*
All {@code Lock} implementations must enforce the same
* memory synchronization semantics as provided by the built-in monitor
* lock, as described in
* The Java Language Specification (17.4 Memory Model):
*
*
A successful {@code lock} operation has the same memory* synchronization effects as a successful Lock action.
*
A successful {@code unlock} operation has the same* memory synchronization effects as a successful Unlock action.
*
*
* Unsuccessful locking and unlocking operations, and reentrant
* locking/unlocking operations, do not require any memory
* synchronization effects.
*
*
Implementation Considerations
*
*
The three forms of lock acquisition (interruptible,
* non-interruptible, and timed) may differ in their performance
* characteristics, ordering guarantees, or other implementation
* qualities. Further, the ability to interrupt the ongoing
* acquisition of a lock may not be available in a given {@code Lock}
* class. Consequently, an implementation is not required to define
* exactly the same guarantees or semantics for all three forms of
* lock acquisition, nor is it required to support interruption of an
* ongoing lock acquisition. An implementation is required to clearly
* document the semantics and guarantees provided by each of the
* locking methods. It must also obey the interruption semantics as
* defined in this interface, to the extent that interruption of lock
* acquisition is supported: which is either totally, or only on
* method entry.
*
*
As interruption generally implies cancellation, and checks for
* interruption are often infrequent, an implementation can favor responding
* to an interrupt over normal method return. This is true even if it can be
* shown that the interrupt occurred after another action may have unblocked
* the thread. An implementation should document this behavior.
*
* @see ReentrantLock
* @see Condition
* @see ReadWriteLock
*
* @since 1.5
* @author Doug Lea
*/
Lock接口提供了一些方法规范,如下所示。
/*** Acquires the lock.**
If the lock is not available then the current thread becomes* disabled for thread scheduling purposes and lies dormant until the* lock has been acquired.* 如果锁不可用,则当前线程将出于线程调度目的而禁用,并处于休眠状态,直到获得锁为止*
Implementation Considerations**
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.*/
void lock();
获取锁,如果锁不可用,则阻塞当前线程。
/*** Acquires the lock unless the current thread is* {@linkplain Thread#interrupt interrupted}.**
Acquires the lock if it is available and returns immediately.**
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:**
- *
- The lock is acquired by the current thread; or*
- Some other thread {@linkplain Thread#interrupt interrupts} the* current thread, and interruption of lock acquisition is supported.*
If the current thread:*
- *
- has its interrupted status set on entry to this method; or*
- is {@linkplain Thread#interrupt interrupted} while acquiring the* lock, and interruption of lock acquisition is supported,*
Implementation Considerations**
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.**
An implementation can favor responding to an interrupt over* normal method return.**
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;
/*** Acquires the lock only if it is free at the time of invocation.**
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}.**
A typical usage idiom for this method would be:*
{@code* Lock lock = ...;* if (lock.tryLock()) {* try {* // manipulate protected state* } finally {* lock.unlock();* }* } else {* // perform alternative actions* }}** 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();
/*** Releases the lock.**
Implementation Considerations**
A {@code Lock} implementation will usually impose* restrictions on which thread can release a lock (typically only the* holder of the lock can release it) and may throw* an (unchecked) exception if the restriction is violated.* Any restrictions and the exception* type must be documented by that {@code Lock} implementation.*/
void unlock();
/*** Returns a new {@link Condition} instance that is bound to this* {@code Lock} instance.**
Before waiting on the condition the lock must be held by the* current thread.* A call to {@link Condition#await()} will atomically release the lock* before waiting and re-acquire the lock before the wait returns.**
Implementation Considerations**
The exact operation of the {@link Condition} instance depends on* the {@code Lock} implementation and must be documented by that* implementation.** @return A new {@link Condition} instance for this {@code Lock} instance* @throws UnsupportedOperationException if this {@code Lock}* implementation does not support conditions*/
Condition newCondition();