Lock和Condition只是concurrent中的两个接口,但基于这两个接口实现的类完成了先前由synchronized和object共同实现的方法。
但就生产者消费者来说(参考生产者与消费者),Lock相当于synchronized,而Condition的await()和signal()方法相当于Object的wait()和notify()方法。
在讲解Lock和Condition之前,先要弄清synchronized的本质:
synchronized(Object o)代码块实际上获得了对象o的锁才会继续执行里面的方法,而对象o的锁只有一把,因此针对某一个对象o的synchronized代码块只能串行执行。
其实往深了就是锁,既然是锁,那么我们肯定可以直接使用锁的方法来完成synchronized的功能。
Lock
上面说道,使用Lock代替synchronized,那么Lock接口到底有哪些作用呢?
总的来说,Lock可以完全替换synchronized,并在此基础上提供了更多的功能。
其源码如下:
public interface Lock {
/**
* 当前线程获取lock的锁,如果获取不到,则当前线程就暂停
* 相当于synchronized(lock)方法
*/
void lock();
//获取锁,相当于lock(),但可以被打断
void lockInterruptibly() throws InterruptedException;
/**
* 非阻塞式的获取锁,如果获取不到就返回false,该方法不会导致当前的阻塞
* 对于tryLock(),常见的方法是:
* Lock lock = ...;
* if (lock.tryLock()) {
* try {
* // manipulate protected state
* } finally {
* lock.unlock();
* }
* } else {
* // perform alternative actions
* }
*/
boolean tryLock();
//同tryLock()
boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
//释放锁,正如上面的例子,该方法一般在finally方法中
void unlock();
/*
* 返回和该锁对应的Condition对象。
* 方法本身很难理解,需要对照例子和Condition源码
* 实际上相当于和synchronized(Object o)对应的o
*/
Condition newCondition();
以上是Lock的源码,Lock基本实现了互斥锁,但单独的Lock是无法实现条件获取,即调用lock()方法时没有指定条件,因此单独的lock无法实现生产者消费者功能,而条件获取锁还需要另外通过Condition来辅助完成。
Condition
Condition将Object的wait()和notify()方法独立了出来,直接看看Condition的源码:
public interface Condition {
/**
* 使得当前线程等待
* 类似于Object.wait()方法
* 该等待可以被打断
*/
void await() throws InterruptedException;
/*
* 同样是等待,但该方法不会被打断
* 不管是await()还是awaitUninterruptibly(),在调用时都需要
* 已经获得和Condition相关的锁
* 而调用await()或者awaitUninterruptibly()后则自动释放锁
* 而在从await()执行完毕,方法返回时则需要再次获取锁
*/
void awaitUninterruptibly();
long awaitNanos(long nanosTimeout) throws InterruptedException;
boolean await(long time, TimeUnit unit) throws InterruptedException;
boolean awaitUntil(Date deadline) throws InterruptedException;
/**
* 唤醒一个等待的线程
* 相当于Object.notify()方法
*/
void signal();
//相当于Object.notifyAll()方法
void signalAll();
通过分析Condition的源码,发现Condition确实就是相当于Object的wait()和notify()方法的替代。
但这里有一个问题,我们在上一篇博客分析了。
synchronized(Object o) 和o.wait()配合使用,其中o起着中间承接的作用,那么对于Condition和Lock,这两如何配合起来呢?其实就是通过Lock的newCondition()方法来承接的,即Condition c = lock.newCondition()。