1.Condition实现等待和唤醒线程

java.util.locks.ReentrantLock用于替代synchronized加锁



但是synchronized可以使用wait和notify实现线程在条件不满足时的等待,条件满足时的唤醒。

如何使用ReentrantLock实现wait/notify的功能?

这个时候我们可以使用Condition对象来实现条件不满足时的等待,条件满足时的唤醒。

class TaskQueue{
final Lock lock = new ReentrantLock()
final Condition notEmpty = lock.newCondition();
}

1.1 对Condition对象调用await()方法就相当于对所对象调用wait()方法。


### 1.2 对Condition对象调用signalAll()就相当于在synchronized加锁对象调用notifyAll()方法。

Condition.await/signal/signalAll原理和wait/notify/notifyAll一致
* await()会释放当前锁,进入等待状态
* signal()会唤醒某个等待线程
* signalAll()会唤醒所有等待线程
* 唤醒线程从await()返回后需要重新获得锁

2. 示例

import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock; class TaskQueue{
final Queue<String> queue = new LinkedList<>();
final Lock lock = new ReentrantLock();
final Condition notEmpty = lock.newCondition();
public String getTask() throws InterruptedException{
lock.lock();
try{
while(this.queue.isEmpty()){
notEmpty.await();
}
return queue.remove();
}finally {
lock.unlock();
}
}
public void addTask(String name){
lock.lock();
try{
this.queue.add(name);
notEmpty.signalAll();
}finally {
lock.unlock();
}
}
}
class WorkerThread extends Thread{
TaskQueue taskQueue;
public WorkerThread(TaskQueue taskQueue){
this.taskQueue = taskQueue;
}
public void run(){
while(!isInterrupted()){
String name;
try{
name = taskQueue.getTask();
}catch (InterruptedException e){
break;
}
String result = "Hello, "+name+" !";
System.out.println(result);
}
}
}
public class Main{
public static void main(String[] args) throws InterruptedException{
TaskQueue taskQueue = new TaskQueue();
WorkerThread worker = new WorkerThread(taskQueue);
worker.start();
taskQueue.addTask("Bob");
Thread.sleep(1000);
taskQueue.addTask("Alice");
Thread.sleep(1000);
taskQueue.addTask("Tim");
Thread.sleep(1000);
worker.interrupt();
worker.join();
System.out.println("END");
}
}


## 3. 总结
使用ReentrantLock+Condition可以更安全的实现线程的同步、等待和唤醒。
* Condition可以替代wait/notify
* Condition对象必须从ReentrantLock对象获取
* ReentrantLock+Condition可以替代synchronized+wait/notify

廖雪峰Java11多线程编程-3高级concurrent包-3Condition的更多相关文章

  1. 廖雪峰Java11多线程编程-3高级concurrent包-5Atomic

    Atomic java.util.concurrent.atomic提供了一组原子类型操作: 如AtomicInteger提供了 int addAndGet(int delta) int increm ...

  2. 廖雪峰Java11多线程编程-3高级concurrent包-4Concurrent集合

    Concurrent 用ReentrantLock+Condition实现Blocking Queue. Blocking Queue:当一个线程调用getTask()时,该方法内部可能让给线程进入等 ...

  3. 廖雪峰Java11多线程编程-3高级concurrent包-1ReentrantLock

    线程同步: 是因为多线程读写竞争资源需要同步 Java语言提供了synchronized/wait/notify来实现同步 编写多线程同步很困难 所以Java提供了java.util.concurre ...

  4. 廖雪峰Java11多线程编程-3高级concurrent包-6ExecutorService

    Java语言内置多线程支持: 创建线程需要操作系统资源(线程资源,栈空间) 频繁创建和销毁线程需要消耗大量时间 如果可以复用一个线程 线程池: 线程池维护若干个线程,处于等待状态 如果有新任务,就分配 ...

  5. 廖雪峰Java11多线程编程-3高级concurrent包-9Fork_Join

    线程池可以高效执行大量小任务: Fork/Join线程池可以执行一种特殊的任务: 把一个大任务拆成多个小任务并行执行 Fork/Join是在JDK 1.7引入的 示例:计算一个大数组的和 Fork/J ...

  6. 廖雪峰Java11多线程编程-3高级concurrent包-8CompletableFuture

    使用Future可以获得异步执行结果 Future<String> future = executor.submit(task); String result = future.get() ...

  7. 廖雪峰Java11多线程编程-3高级concurrent包-7Future

    JDK提供了ExecutorService接口表示线程池,可以通过submit提交一个任务. ExecutorService executor = Executors.newFixedThreadPo ...

  8. 廖雪峰Java11多线程编程-3高级concurrent包-2ReadWriteLock

    ReentrantLock保证单一线程执行 ReentrantLock保证了只有一个线程可以执行临界区代码: 临界区代码:任何时候只有1个线程可以执行的代码块. 临界区指的是一个访问共用资源(例如:共 ...

  9. 廖雪峰Java11多线程编程-2线程同步-3死锁

    1.线程锁可以嵌套 在多线程编程中,要执行synchronized块: 必须首先获得指定对象的锁 Java的线程锁是可重入的锁.对同一个对象,同一个线程,可以多次获取他的锁,即同一把锁可以嵌套.如以下 ...

随机推荐

  1. project3_NeedToLoginCalculator(需要进行登陆确认的计算器)

    下列实现代码说明: 下列代码主要是实现计算器功能.由于之前在莫凡老师开设的<用 python 和 tkinter 做简单的窗口视窗>课程当中学习了tkinter的内容,在该课程的结束部分是 ...

  2. Unity NGUI 粒子的排序

    Unity NGUI系统中是没有对粒子进行排序的,如: 怎么解决这个问题呢? 思路是把粒子的渲染层级,相对于UI组件的层级进行一个偏移. 解决后的效果如下: 代码如下: using System.Co ...

  3. socket的多线程实现

    步骤: 1.服务端创建ServerSocket,循环调用accept()等待客户端连接: 2.客户端创建socket并请求与服务端对话: 3.服务端接收客户端的请求,创建socket与客户端进行专线连 ...

  4. Python3入门机器学习经典算法与应用✍✍✍

    Python3入门机器学习经典算法与应用 整个课程都看完了,这个课程的分享可以往下看,下面有链接,之前做java开发也做了一些年头,也分享下自己看这个视频的感受,单论单个知识点课程本身没问题,大家看的 ...

  5. C++之数据类型--整形&sizeof关键字

    数据类型: C++规定在创建一个变量或者常量时,必须要指定出相应的数据类型,否则无法给变量分配内存 整型 **作用**:整型变量表示的是==整数类型==的数据 C++中能够表示整型的类型有以下几种方式 ...

  6. 43个实例xHTML+CSS(DIV+CSS)网页及导航布局

    在中国,很多前端开发初学者都会把xHTML+CSS页面制作说成DIV+CSS,甚至很多人都还不知道xHTML+CSS是什么意思,只知道盲目的追求DIV+CSS,但在国外,是没有DIV+CSS这个概念的 ...

  7. vue项目使用history模式打包应该注意的地方

    1.在config/index.js中将assetsPublicPath原来的’/‘修改为‘./’. build: { env: require('./prod.env'), index: path. ...

  8. CSS动画库——animate.css的使用

    Animate.css是一款强大的CSS3动画库 官网地址:https://daneden.github.io/animate.css/ 使用方法如下所示: (1)下载animate.css 下载地址 ...

  9. 安装Epson打印机但因lsb依赖错误而中断的驱动程序

    sudo apt-get install printer-driver-escpr 安装Epson打印机但因lsb依赖错误而中断的驱动程序 问题: 我正在安装 Epson XP-310 驱动程序,从这 ...

  10. CF431E Chemistry Experiment

    题意:有n个试管,有高度为hi的水银.操作1:将试管x中的水银高度改成y.操作2:将体积为v的水注入试管,求水位的高度?n,q<=1e5. 标程: #include<bits/stdc++ ...