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包下提供了三个实现类:
