public interface Lock
Lock
实现提供更广泛的锁定操作可以比使用
synchronized
获得方法和报表。他们允许更灵活的结构,可以有完全不同的特性,可以支持多个相关的
Condition
对象。
锁是一种通过多个线程控制对共享资源的访问的工具。通常,一个锁提供对共享资源的独占访问:在一个时间只有一个线程可以获得锁和所有访问共享资源,需要先获得锁。然而,有些锁可以允许并发访问共享资源,如一个ReadWriteLock
读锁。
对synchronized
方法或报表提供了访问每个对象相关的隐式监视器锁的使用,但部队的所有锁的获取和释放在一个结构化的方式发生:当多个锁的获得必须以相反的顺序释放,和所有的锁必须释放相同的词法范围,他们获得。
而作用机制synchronized
方法和语句使它与监控锁程序更容易,并有助于避免许多常见的编程错误的锁,有时需要使用锁以更灵活的方式。例如,一些遍历并发访问的数据结构的算法需要使用“手在手”或“链锁”:你获得的锁的节点A,然后节点B,然后释放A和获取C,然后释放B和获取D等。该Lock
接口实现使通过允许一个锁被获取和在不同范围内发布这样的技术的使用,并允许多个锁被获取和发布任何命令。
随着这种增加的灵活性来增加额外的责任。块没有锁定解除锁结构与synchronized
方法和报表时自动释放。在大多数情况下,应该使用以下的成语:
Lock l = ...;
l.lock();
try {
// access the resource protected by this lock
} finally {
l.unlock();
}
当锁定和解锁在不同的范围时,必须注意确保所有的代码,而持有锁的执行受终于尝试或尝试抓住确保锁被释放时。
Lock
实现提供额外的功能来提供一个非阻塞的尝试获取锁的synchronized
方法和语句的使用(tryLock()
),企图获取锁,可以中断(lockInterruptibly()
,并试图获取锁,超时(tryLock(long, TimeUnit)
)。
一个Lock
类还可以提供行为和语义,从隐含的监视器锁完全不同,例如保证订货,不可重入的用法,或死锁检测。如果一个实现提供了这样的专门的语义,那么这些语义的实现必须记录这些语义。
注意,Lock
实例仅仅是普通的对象,也可以被用来作为目标在synchronized
声明。获取一个Lock
实例监控锁没有关系的任何指定调用该实例的lock()
方法。这是建议,为了避免混淆,你这样没用Lock
实例,除了在自己的实现。
除特别注明外,传递任何参数null
值将导致NullPointerException
抛出。
所有的Lock
实现必须执行相同的内存同步语义的内置监控锁提供,如 The Java Language Specification (17.4 Memory Model):
lock
操作具有相同的内存同步的影响作为一个成功的锁定动作。unlock
操作具有相同的内存同步的影响作为一个成功的解锁行动。三种获取锁(可中断,不可中断,定时)可能会有不同的性能特点,有序的保证,或其他实施素质。此外,中断锁正在采集能力不可能在一个给定的Lock
类可。因此,一个实现是不需要定义完全相同的保证或语义的所有三种形式的锁收购,也不是需要支持中断正在进行的锁定收购。一个实现是需要清楚地记录的语义和保证提供的每一个锁定方法。它也必须服从中断的语义定义在这个接口中,锁定收购的中断的程度是支持:这是完全,或仅在方法进入。
由于中断通常意味着取消,和检查中断往往是罕见的,一个实现可以有利于响应一个中断,在正常的方法返回。即使它可以表明,中断发生后,另一个行动可能有畅通的线,这是真的。一个实现应该记录这种行为。
ReentrantLock
,
Condition
,
ReadWriteLock
Modifier and Type | Method and Description |
---|---|
void |
lock()
获取锁。
|
void |
lockInterruptibly()
获取该锁除非当前线程
interrupted。
|
Condition |
newCondition()
返回一个新的
Condition 实例绑定到该
Lock 实例。
|
boolean |
tryLock()
只有在调用时释放该锁,才能获取锁。
|
boolean |
tryLock(long time, TimeUnit unit)
获取锁,如果它是免费的在给定的等待时间和当前线程没有被
interrupted。
|
void |
unlock()
释放锁。
|
void lock()
如果没有可用的锁,那么当前的线程成为禁用线程调度的目的,并处于休眠状态,直到锁已被收购。
实施的思考
一个Lock
实现也许能够检测到锁的错误使用,如一个调用,会导致死锁,并可能引发(没有)在这种情况下例外。情况和异常类型必须由Lock
实施记录。
void lockInterruptibly() throws InterruptedException
获取锁,如果它是可用的,并立即返回。
如果锁不可用,那么当前线程将禁用线程调度的目的,并处于休眠状态,直到两个事情发生:
如果当前线程:
InterruptedException
投入和当前线程的中断状态被清除。
实施的思考
中断在某些实现中的锁收购的能力可能是不可能的,如果可能的话可能是一个昂贵的操作。程序员应该意识到,这可能是这样的情况。当情况是这样的时候,一个实现应该文档。
一个实现可以支持响应于正常方法返回的中断。
一个Lock
实现也许能够检测到锁的错误使用,如一个调用,会导致死锁,并可能引发(没有)在这种情况下例外。情况和异常类型必须由Lock
实施记录。
InterruptedException
如果当前线程在获取锁(锁中断和中断采集支持)
boolean tryLock()
获取该锁是否可用,立即返回的值true
。如果锁不可用,那么这个方法会立即返回的值false
。
这种方法的一个典型的用法是:
Lock lock = ...;
if (lock.tryLock()) {
try {
// manipulate protected state
} finally {
lock.unlock();
}
} else {
// perform alternative actions
}
这种用法确保锁是否获得解锁,并没有试图解开如果锁没有获得。
true
如果锁被收购和
false
否则
boolean tryLock(long time, TimeUnit unit) throws InterruptedException
如果锁可用此方法立即返回的值true
。如果锁不可用,则当前线程的线程调度的目的成为残疾人和处于休眠状态,直到三个事情发生:
如果锁是后天再true
返回值。
如果当前线程:
InterruptedException
投入和当前线程的中断状态被清除。
如果指定的等待时间的流逝,然后false
返回值。如果时间小于或等于零,该方法将不会等待在所有。
实施的思考
中断在某些实现中的锁收购的能力可能是不可能的,如果可能的话可能是一个昂贵的操作。程序员应该意识到,这可能是这样的情况。当情况是这样的时候,一个实现应该文档。
一个实现可以支持响应于正常方法返回的中断,或报告超时。
一个Lock
实现也许能够检测到锁的错误使用,如一个调用,会导致死锁,并可能引发(没有)在这种情况下例外。情况和异常类型必须由Lock
实施记录。
time
-最大时间等待锁
unit
的
time
争论的时间单位
true
如果锁被收购和
false
如果等待的时间才获得锁
InterruptedException
如果当前线程在获取锁(锁中断和中断采集支持)
void unlock()
实施的思考
一个Lock
实施通常会限制线程释放锁(通常只有锁的持有者可以释放它)可能抛出(没有)例外,如果限制了。任何的限制和例外的类型必须由Lock
实施记录。
Condition newCondition()
Condition
实例绑定到该
Lock
实例。
在等待条件之前,锁必须由当前线程保持。一个叫Condition.await()
会自动释放锁之前,等待重新返回前等待获取锁。
实施的思考
该Condition
实例的具体操作,取决于Lock
实施必须由实施记录。
Condition
Lock
实例实例
UnsupportedOperationException
-如果这
Lock
实现不支持条件
Submit a bug or feature
For further API reference and developer documentation, see Java SE Documentation. That documentation contains more detailed, developer-targeted descriptions, with conceptual overviews, definitions of terms, workarounds, and working code examples.
Copyright © 1993, 2014, Oracle and/or its affiliates. All rights reserved.