Lock implementations provide more extensive locking operations than can be obtained using synchronized methods and statements. They allow more flexible structuring, may have quite different properties, and may support multiple associated Condition objects.
锁的实现提供了比 synchroized 更广泛的”锁“操作,而且使用它的时候更灵活一些,它可以有不同的属性,还可以提供多关联条件的objects。
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 ReadWriteLock.
锁是一种控制多线程访问共享资源可用性的工具,通常来说锁对共享资源提供一个独占访问: 在一个时间内只有一个线程可以获取这个锁,所有访问这个共享资源都需要先获取这个锁,比如说 ReadWriteLock(读写锁) 的"读锁"。
The use of 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 可访问与每个对象关联的隐式监视器锁,但是会强制所有锁的获取和释放以块结构的方式发生: 当多个锁被获取后,他们必须以相反的顺序释放,并且所有锁必须在同一个scope(获取锁的scope)中被释放。
While the scoping mechanism for 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 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.
因为 scope 机制使得 synchronized 使用起来比较简单,同时也能避免关于”锁“的常见编程错误,有些时候我们需要更灵活的使用"锁", 例如,某些用于遍历并发访问数据结构的算法需要使用"hand-over-hand"或 “chain locking”: 你需要获取节点A的锁,然后获取节点B的锁,然后释放A的锁获取C的锁,然后释放B的锁获取D的锁等等。实现lock接口可以允许在不同scope内获取和释放锁,并允许以任意顺序获取和释放多个锁.
With this increased flexibility comes additional responsibility. The absence of block-structured locking removes the automatic release of locks that occurs with synchronized methods and statements. In most cases, the following idiom should be used:
灵活性的提高带来了更多的责任。 缺少块结构的"锁" 将不会像使用 synchronized 那样自动释放锁。 在大多数情况下,应使用以下惯用法:
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.
当获取锁或者释放锁发生在不同的scope时,一定要确保所执行的代码都要被try-finally或者try-catch包裹,这样可以保证"锁"在必要的时候可以释放。
Lock implementations provide additional functionality over the use of synchronized methods and statements by providing a non-blocking attempt to acquire a lock (#tryLock()), an attempt to acquire the lock that can be interrupted (#lockInterruptibly), and an attempt to acquire the lock that can timeout (#tryLock(long, TimeUnit)).
锁的实现提供了一些附加的功能,如非阻塞的去尝试获取一个锁(#tryLock()), 尝试获取锁的时候可以被中断(#lockInterruptibly), 获取锁的时候可以设置超时时间(#tryLock(long, TimeUnit))。
A Lockclass 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.
一个 Lock 还可以提供与"隐式监视器锁" 不同的行为和语义。如保证顺序, 不能重复使用, 死锁检测。 如果锁的实现提供了这些特殊的语义,必须要通过文档来说明这些语义。
Note that Lock instances are just normal objects and can themselves be used as the target in a synchronized statement. Acquiring the monitor lock of a Lock instance has no specified relationship with invoking any of the #lock methods of that instance. It is recommended that to avoid confusion you never use Lock instances in this way, except within their own implementation.
一个"锁"其实就是一个普通的 object,所以他自身也可以被用于synchronized 中, 获取一个"锁"的监视器锁和这个锁实例的lock方法没有什么特别的关系, 为了避免这种迷惑,我们不应该将synchronized和锁混合使用。
Except where noted, passing a null value for any
parameter will result in a NullPointerException being
thrown.
特别要注意的是,任何参数值都不能为null,如果为null的话,将会抛出NullPointerException异常。
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.
由于中断通常意味着取消,并且打断的检查并不是很频繁,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. 文档应该记录这种表现。
两种锁的实现会在之后介绍
ReentrantLock (重入锁)
ReadWriteLock (读写锁)