1 概述
我们知道针对synchronized关键字实现的加锁操作操作我们可以使用wait和notify来实现线程的等待和唤醒线程,但是我们清楚这个时候就只能有一个线程进入等待,那么如果我们想要多个线程等待,同时我们可以唤醒多个线程怎么办呢?这个时候就需要用到Lock对应的Condition来完成了。
我们知道针对Lock与synchronized的区别在于,Lock的操作更加灵活,并且可以响应超时等待和中断。我们下面就来看一看Contidion具体是如何使用的。
2 示例
/**
* 演示Condition的使用
* @author: LIUTAO
* @Date: Created in 2018/9/3 10:12
* @Modified By:
*/
public class ConditionDemo {
public static void main(String[] args) {
ReentrantLock reentrantLock = new ReentrantLock();
Condition condition = reentrantLock.newCondition();
new Thread(() -> {
reentrantLock.lock();
System.out.println(Thread.currentThread().getName()+"get lock successfully");
System.out.println(Thread.currentThread().getName()+"waiting signal");
try {
condition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+" get signal successfully");
reentrantLock.unlock();
},"first thread ").start();
new Thread(() -> {
reentrantLock.lock();
System.out.println(Thread.currentThread().getName()+"get lock successfully");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"send signal");
condition.signalAll();
System.out.println(Thread.currentThread().getName()+" get signal successfully");
reentrantLock.unlock();
},"second thread ").start();
}
}
运行上面的代码,我们可以看见如下输出:
first thread get lock successfully
first thread waiting signal
second thread get lock successfully
second thread send signal
second thread get signal successfully
first thread get signal successfully
我们可以看出在first thread调用了condition.await()后,first thread让出了锁,然后second thread 获取到锁。而当second thread调用condition.signalAll()的时候又让出了锁,first thread获取到锁。这就实现了线程的等待和唤醒。
我们需要注意的是Condition的使用必须在lock()和unlock()方法之间。
3 函数说明
这里我们针对Condition具有的函数进行一个简单的介绍。
await():使当前线程等待,同时释放当前锁,当其他线程中使用signal()时或者signalAll()方法时,线程会重新获得锁并继续执行。或者当线程被中断时,也能跳出等待。该方法和Object的wait()类似。
awaitUninterruptibly():该方法和await()相同,但是不响应中断。
await(long time, TimeUnit unit):当前线程等待,直到线程被唤醒或者中断,或者等待时间耗尽,这里第二个参数就是等待时间单位。
awaitNanos(long nanosTimeout):当前线程等待,直到线程被唤醒或者中断,或者等待时间耗尽,等待的时间单位是固定的为纳秒(十亿分之一秒)。
awaitUntil(Date deadline):前线程等待,直到线程被唤醒或者中断,或者到达具体的截至日期。
signal():唤醒一个等待的线程。
signalAll():唤醒所有等待的线程。
4 和Object的wait()与notify()的区别
(1)Object的一个对象只能又一个等待队列,而针对Lock,一个对象可以有多个等待等待队列。
(2)使用Lock比使用Object加锁的方式具有更好的灵活性。可以响应中断和设置获取锁的超时间。
(3)Lock支持公平性和非公平性的设置,而synchronized不支持。
以上就是针对Condition使用的详解,下面的文章我们将继续学习Condition源码的实现。