Lock接口
1. Lock简介
Lock锁实现提供了比使用synchronized同步方法和语句更广泛的锁操作。它们允许更灵活的结构,可能具有非常不同的属性,并且可能支持多个关联的条件对象。Lock提供了比synchronized更多的功能。 Lock与的Synchronized区别
- Lock不是Java语言内置的,synchronized是Java语言的关键字,因此是内置特性。Lock是一个类,通过这个类可以实现同步访问;
- Lock和synchronized有一点非常大的不同,采用synchronized不需要用户去手动释放锁,当synchronized方法或者synchronized代码块执行完之后,系统会自动让线程释放对锁的占用;而Lock则必须要用户去手动释放锁,如果没有主动释放锁,就有可能导致出现死锁现象。
2. Lock接口方法
Lock接口源码如下,主要有6个方法:
java
public interface Lock {
void lock();
void lockInterruptibly() throws InterruptedException;
boolean tryLock();
boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
void unlock();
Condition newCondition();
}
2.1 lock()方法
lock()
方法是平常使用得最多的一个方法,就是用来获取锁。如果锁已被其他线程获取,则进行等待。采用Lock必须主动去释放锁,并且在发生异常时,不会自动释放锁。因此一般来说,使用Lock必须在try{}catch{}块中进行,并且将释放锁的操作放在finally块中进行,以保证锁一定被被释放,防止死锁的发生。通常使用Lock来进行同步的话,是以下面这种形式去使用的:
java
Lock lock = ...;
lock.lock();
try{
//处理任务
}catch(Exception ex){
}finally{
lock.unlock(); //释放锁
}
2.2 newCondition()方法
关键字synchronized与wait()
/notify()
这两个方法一起使用可以实现等待/通知模式,Lock锁的newContition()
方法返回Condition对象,Condition类也可以实现等待/通知模式。用notify()
通知时,JVM会随机唤醒某个等待的线程,使用Condition类可以进行选择性通知,Condition比较常用的两个方法:
await()
会使当前线程等待,同时会释放锁,当其他线程调用signal()
时,线程会重新获得锁并继续执行。signal()
用于唤醒一个等待的线程。
信息
在调用Condition的await()
/signal()
方法前,也需要线程持有相关的Lock锁,调用await()
后线程会释放这个锁,在singal()
调用后会从当前Condition对象的等待队列中唤醒一个线程,唤醒的线程尝试获得锁,一旦获得锁成功就继续执行。
3. Lock的实现类
Lock是一个接口,在java.util.concurrent包下提供了三个实现类: