Most visited

Recently visited

Added in API level 1

Lock

public interface Lock

java.util.concurrent.locks.Lock
Known Indirect Subclasses


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();
 }
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.

Lock实现提供对使用的附加功能 synchronized通过提供一种无阻塞试图获取锁(方法和语句 tryLock() ),在试图获得可被中断(锁定 lockInterruptibly() ,并以获得锁,可以试图超时( tryLock(long, TimeUnit) )。

Lock类还可以提供与隐式监视器锁定非常不同的行为和语义,例如保证排序,非重入使用或死锁检测。 如果实现提供了这种专用语义,那么实现必须记录这些语义。

请注意, Lock实例只是普通对象,并且本身可以用作synchronized语句中的目标。 获取Lock实例的监视器锁与调用该实例的任何lock()方法没有指定的关系。 为避免混淆,建议您不要以这种方式使用Lock实例,除非在其自己的实现中。

除非另有说明, null为任何参数传递 null值都会导致引发 NullPointerException

Memory Synchronization

Lock所述,所有 Lock实现 必须强制执行与内置监视器锁提供的内存同步语义相同的 内容

Unsuccessful locking and unlocking operations, and reentrant locking/unlocking operations, do not require any memory synchronization effects.

Implementation Considerations

获取锁定的三种形式(可中断,不可中断和定时)可能在其性能特征,订购保证或其他实现品质方面有所不同。 此外,在给定的Lock课程中,可能无法中断正在进行的锁的获取。 因此,不需要实现为所有三种形式的锁获取定义完全相同的保证或语义,也不需要支持中断正在进行的锁获取。 需要一个实现来清楚地记录每个锁定方法提供的语义和保证。 它也必须遵守这个接口中定义的中断语义,以支持锁获取的中断:哪一个是完全的,或者仅仅是方法入口。

由于中断通常意味着取消,并且检查中断通常很少发生,所以实现可以有利于响应正常方法返回的中断。 即使可以显示中断发生在另一个操作可能已经解除线程阻塞之后,也是如此。 一个实现应该记录这种行为。

也可以看看:

Summary

Public methods

abstract void lock()

获取锁定。

abstract void lockInterruptibly()

获取锁定,除非当前线程为 interrupted

abstract Condition newCondition()

返回一个新 Condition绑定到该实例 Lock实例。

abstract boolean tryLock()

只有在调用时它是空闲的,才会获取该锁。

abstract boolean tryLock(long time, TimeUnit unit)

如果在给定的等待时间内自由并且当前线程不是 interrupted ,则获取该锁。

abstract void unlock()

释放锁定。

Public methods

lock

Added in API level 1
void lock ()

获取锁定。

如果锁定不可用,则当前线程因为线程调度目的而被禁用,并且处于休眠状态,直到获取锁定。

实施注意事项

Lock实现可能能够检测到锁的错误使用,例如会导致死锁的调用,并且可能会在这种情况下抛出(未检查)异常。 在环境和异常类型必须由记录在案Lock实现。

lockInterruptibly

Added in API level 1
void lockInterruptibly ()

获取锁定,除非当前线程为 interrupted

获取锁定,如果锁定可用并立即返回。

如果锁不可用,则当前线程因为线程调度目的而被禁用,并且处于休眠状态,直到发生以下两件事之一:

  • The lock is acquired by the current thread; or
  • Some other thread interrupts the current thread, and interruption of lock acquisition is supported.

如果当前线程:

  • has its interrupted status set on entry to this method; or
  • is interrupted while acquiring the lock, and interruption of lock acquisition is supported,
then InterruptedException is thrown and the current thread's interrupted status is cleared.

实施注意事项

在一些实现中中断锁获取的能力可能是不可能的,并且如果可能的话可能是昂贵的操作。 程序员应该意识到这可能是这种情况。 一个实施应该记录这种情况。

实现可以有利于响应正常方法返回的中断。

Lock实现可能能够检测到锁的错误使用,例如会导致死锁的调用,并且可能会在此类情况下抛出(未检查)异常。 该情况和异常类型必须由该Lock实施记录。

Throws
InterruptedException if the current thread is interrupted while acquiring the lock (and interruption of lock acquisition is supported)

newCondition

Added in API level 1
Condition newCondition ()

返回一个新 Condition绑定到该实例 Lock实例。

在等待条件之前,锁必须由当前线程保持。 一个await()的调用会在等待之前以原子方式释放锁,并在等待返回之前重新获取该锁。

实施注意事项

Condition实例的确切操作取决于 Lock实现,并且必须由该实现记录。

Returns
Condition A new Condition instance for this Lock instance
Throws
UnsupportedOperationException if this Lock implementation does not support conditions

tryLock

Added in API level 1
boolean tryLock ()

只有在调用时它是空闲的,才会获取该锁。

如果锁可用,则获取该锁,并立即返回值true 如果锁定不可用,则此方法将立即返回值false

这种方法的典型用法习惯是:

 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.

Returns
boolean true if the lock was acquired and false otherwise

tryLock

Added in API level 1
boolean tryLock (long time, 
                TimeUnit unit)

如果在给定的等待时间内空闲并且当前线程不是 interrupted ,则获取该锁。

如果锁定可用,则此方法立即返回值true 如果锁不可用,则当前线程因为线程调度目的而被禁用,并且处于休眠状态,直到发生以下三件事之一:

  • The lock is acquired by the current thread; or
  • Some other thread interrupts the current thread, and interruption of lock acquisition is supported; or
  • The specified waiting time elapses

如果获取锁,则返回值 true

如果当前线程:

  • has its interrupted status set on entry to this method; or
  • is interrupted while acquiring the lock, and interruption of lock acquisition is supported,
then InterruptedException is thrown and the current thread's interrupted status is cleared.

如果经过了指定的等待时间,则返回值false 如果时间小于或等于零,该方法将不会等待。

实施注意事项

在一些实现中中断锁获取的能力可能是不可能的,并且如果可能的话可能是昂贵的操作。 程序员应该意识到这可能是这种情况。 一个实施应该记录这种情况。

实现可以有利于响应正常方法返回的中断,或者报告超时。

一个Lock实现可能能够检测到锁的错误使用,例如会引起死锁的调用,并且可能会在这种情况下抛出(未检查)异常。 在环境和异常类型必须由记录在案Lock实现。

Parameters
time long: the maximum time to wait for the lock
unit TimeUnit: the time unit of the time argument
Returns
boolean true if the lock was acquired and false if the waiting time elapsed before the lock was acquired
Throws
InterruptedException if the current thread is interrupted while acquiring the lock (and interruption of lock acquisition is supported)

unlock

Added in API level 1
void unlock ()

释放锁定。

实施注意事项

一个Lock实现通常会限制哪个线程可以释放一个锁(通常只有锁的持有者才能释放它),并且如果违反限制条件,可能会抛出一个(未检查的)异常。 任何限制和例外类型都必须由该Lock实现记录。

Hooray!