当前位置: 首页 > wzjs >正文

一个人做网站 优帮云html在线编程网站

一个人做网站 优帮云,html在线编程网站,网站制作网站开发,受欢迎的天津网站建设引入 上一篇关于Condition,我们对Condition有了进一步了解,在之前生产/消费者模式一文,我们讲过如何用 Condition 和 wait/notify 来实现生产者/消费者模式,其中的精髓就在于用Condition 和 wait/notify 来实现简易版阻塞队列&am…

引入

上一篇关于Condition,我们对Condition有了进一步了解,在之前生产/消费者模式一文,我们讲过如何用 Condition 和 wait/notify 来实现生产者/消费者模式,其中的精髓就在于用Condition 和 wait/notify 来实现简易版阻塞队列,我们先来分别回顾一下这两段代码。

用 Condition 实现简易版阻塞队列

代码如下所示:

import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
/*** 一个使用 Condition 实现的阻塞队列类。* 该类提供了一个线程安全的队列,支持在队列满时阻塞插入操作,* 在队列空时阻塞移除操作。*/
public class MyBlockingQueueForCondition {// 存储元素的队列private Queue queue;// 队列的最大容量private int max = 16;// 用于线程同步的可重入锁private ReentrantLock lock = new ReentrantLock();// 当队列不为空时的条件private Condition notEmpty = lock.newCondition();// 当队列不为满时的条件private Condition notFull = lock.newCondition();/*** 构造函数,初始化队列的最大容量。* * @param size 队列的最大容量*/public MyBlockingQueueForCondition(int size){this.max = size;queue = new LinkedList();}/*** 向队列中插入一个元素。* 如果队列已满,线程将被阻塞,直到队列有空间。* * @param o 要插入的元素* @throws InterruptedException 如果线程在等待时被中断*/public void put(Object o) throws InterruptedException {// 获取锁lock.lock();try {// 当队列已满时,线程等待while (queue.size() == max) {notFull.await();}// 向队列中添加元素queue.add(o);// 通知所有等待队列不为空的线程notEmpty.signalAll();} finally {// 释放锁lock.unlock();}}/*** 从队列中移除并返回一个元素。* 如果队列为空,线程将被阻塞,直到队列中有元素。* * @return 队列中的第一个元素* @throws InterruptedException 如果线程在等待时被中断*/public Object take() throws InterruptedException {// 获取锁lock.lock();try {// 当队列为空时,线程等待while (queue.size() == 0) {notEmpty.await();}// 从队列中移除并获取元素Object item = queue.remove();// 通知所有等待队列不为满的线程notFull.signalAll();return item;} finally {// 释放锁lock.unlock();}}
}

在上面的代码中,首先定义了一个队列变量 queue,其最大容量是 16;然后定义了一个ReentrantLock 类型的 Lock 锁,并在 Lock 锁的基础上创建了两个 Condition,一个是 notEmpty,另一个是 notFull,分别代表队列没有空和没有满的条件;最后,声明了 put 和 take 这两个核心方法。

用 wait/notify 实现简易版阻塞队列

我们再来看看如何使用 wait/notify 来实现简易版阻塞队列,代码如下:

import java.util.LinkedList;
/*** 自定义阻塞队列类,使用 wait() 和 notifyAll() 方法实现线程同步。*/
public class MyBlockingQueueForWaitNotify {/*** 队列的最大容量*/private int maxSize;/*** 存储队列元素的链表*/private LinkedList<Object> storage;/*** 构造函数,初始化队列的最大容量和存储链表。** @param size 队列的最大容量*/public MyBlockingQueueForWaitNotify (int size) {// 将传入的最大容量赋值给类的成员变量this.maxSize = size;// 初始化存储链表storage = new LinkedList<>();}/*** 向队列中添加一个元素。如果队列已满,则线程进入等待状态。** @throws InterruptedException 如果线程在等待过程中被中断*/public synchronized void put() throws InterruptedException {// 当队列已满时,当前线程进入等待状态while (storage.size() == maxSize) {this.wait();}// 向队列中添加一个新元素storage.add(new Object());// 唤醒所有等待的线程this.notifyAll();}/*** 从队列中取出一个元素。如果队列为空,则线程进入等待状态。** @throws InterruptedException 如果线程在等待过程中被中断*/public synchronized void take() throws InterruptedException {// 当队列为空时,当前线程进入等待状态while (storage.size() == 0) {this.wait();}// 从队列中移除并打印第一个元素System.out.println(storage.remove());// 唤醒所有等待的线程this.notifyAll();}
}

如代码所示,最主要的部分仍是 put 与 take 方法。我们先来看 put 方法,该方法被 synchronized 保护,while 检查 List 是否已满,如果不满就往里面放入数据,并通过 notifyAll() 唤醒其他线程。同样,take 方法也被 synchronized 修饰,while 检查 List 是否为空,如果不为空则获取数据并唤醒其他线程。

在生产/消费者模式中,有对这两段代码的详细讲解,遗忘的小伙伴可以到前面复习一下。

Condition 和 wait/notify的关系

对比上面两种实现方式的 put 方法,会发现非常类似,此时让我们把这两段代码同时列在屏幕中,然后进行对比:

public void put(Object o) throws InterruptedException {lock.lock();try {while (queue.size() == max) {notFull.await();}queue.add(o);notEmpty.signalAll();} finally {lock.unlock();}
}
public synchronized void put() throws InterruptedException {while (storage.size() == maxSize) {this.wait();}storage.add(new Object()); this.notifyAll();
}

可以看出,左侧是 Condition 的实现,右侧是 wait/notify 的实现:

  • lock.lock() 对应进入 synchronized 方法
  • condition.await() 对应 object.wait()
  • condition.signalAll() 对应 object.notifyAll()
  • lock.unlock() 对应退出 synchronized 方法

实际上,如果说 Lock 是用来代替 synchronized 的,那么 Condition 就是用来代替相对应的 Object 的wait/notify/notifyAll,所以在用法和性质上几乎都一样。

Condition 把 Object 的 wait/notify/notifyAll 转化为了一种相应的对象,其实现的效果基本一样,但是把更复杂的用法,变成了更直观可控的对象方法,是一种升级。

await 方法会自动释放持有的 Lock 锁,和 Object 的 wait 一样,不需要自己手动释放锁。

另外,调用 await 的时候必须持有锁,否则会抛出异常,这一点和 Object 的 wait 一样。

总结

Condition 是对 wait/notify 的改进和扩展,提供了更高的灵活性和可读性。如果需要更复杂的线程通信机制,建议使用 Condition;如果场景简单,可以继续使用 wait/notify。

下面我们梳理总结一下,核心异同,以及各自适用场景:

相似点

目的相同:两者都是用于实现线程间的通信和同步。它们允许一个线程等待某个条件满足,然后由另一个线程通知它条件已经满足,从而继续执行。

等待和通知机制:都涉及线程进入等待状态,然后被其他线程通知唤醒。在等待期间,线程会释放锁,以便其他线程可以进入同步块修改共享状态。

线程通信:两者都用于线程间的通信,允许线程等待或唤醒其他线程。

需要锁:两者都需要与锁配合使用,wait/notify 依赖 synchronized,而 Condition 依赖 Lock。

不同点

特性wait/notifyCondition
锁的管理隐式锁(通过 synchronized)显式锁(通过 Lock)
灵活性较低,只能有一个等待队列较高,可以有多个条件变量(多个等待队列)
可读性较低,代码容易变得复杂较高,代码更清晰
中断处理不支持中断支持中断(awaitUninterruptibly() 等)
等待条件无法指定多个条件可以指定多个条件(newCondition())

适用场景

wait/notify:适用于简单的线程通信场景。

在 Java 中,wait、notify和notifyAll是Object类的方法。当一个线程调用一个对象的wait方法时,它会进入等待状态,直到另一个线程调用同一个对象的notify或notifyAll方法。通常在使用synchronized关键字实现同步的时候使用。例如,一个线程在同步块中调用wait方法等待某个条件,另一个线程在同步块中改变了这个条件后调用notify或notifyAll方法通知等待的线程。

Condition:适用于复杂的线程通信场景,尤其是需要多个条件变量的场景。

在 Java 中,Condition是在java.util.concurrent.locks包下的一个接口,它是对传统的对象监视器方法(如wait、notify和notifyAll)的一种替代,用于更灵活地实现线程间的通信和等待。通常在使用ReentrantLock实现同步的时候,配合Condition来实现线程间的等待和通知。比如,当一个线程需要等待某个条件满足时,它可以调用Condition的await方法进入等待状态,直到另一个线程调用signal或signalAll方法来通知它条件已经满足。


文章转载自:

http://lUY7drcJ.kycxb.cn
http://6BiALiJr.kycxb.cn
http://IJ9HabRu.kycxb.cn
http://wx7ygXBD.kycxb.cn
http://gv9FgJfe.kycxb.cn
http://ZWGKeFnu.kycxb.cn
http://L7PwssKm.kycxb.cn
http://gI1RdBdb.kycxb.cn
http://rcmpHXzq.kycxb.cn
http://eINmIzAK.kycxb.cn
http://sUB8lvqI.kycxb.cn
http://4DGEiHl1.kycxb.cn
http://DWSr3VTt.kycxb.cn
http://XdkreV7k.kycxb.cn
http://Of6wJtSj.kycxb.cn
http://bI6PvPGs.kycxb.cn
http://pXtNEO3o.kycxb.cn
http://BGrbaKL8.kycxb.cn
http://Oexa35WM.kycxb.cn
http://42srcrqf.kycxb.cn
http://QW2PrWMF.kycxb.cn
http://Qdg20DHh.kycxb.cn
http://Ybd5GsLi.kycxb.cn
http://EZjX6AwM.kycxb.cn
http://KYto8uSi.kycxb.cn
http://2fDr761X.kycxb.cn
http://otxGytvT.kycxb.cn
http://TLhmBQPN.kycxb.cn
http://hnjWV5bJ.kycxb.cn
http://LjaFOxjX.kycxb.cn
http://www.dtcms.com/wzjs/696372.html

相关文章:

  • 网站收录查询临沂seo自己动手制作网站
  • 公司建个网站要多少钱seo诊断分析
  • 无法打开建行网站电商网站平台建设视频
  • 如何制作简单网站wordpress 视频网站
  • 做网站怎么上传建筑网站的思想
  • 网站建设方案的重要性成功营销的案例
  • 网站开发语音大数据营销的应用领域
  • 母婴会所 网站源码下载游戏的软件应用
  • 西安建立公司网站的步骤常熟东南开发区人才网
  • 重庆网站建设快忻哪个网站做的系统好
  • 网站开发的服务器是什么中企动力网站icp备案通知
  • 顺德电子画册网站建设wordpress编程视频
  • 如何在百度推广网站wordpress万年历插件
  • 城市建设理论研究收录网站域名ip地址在线查询
  • 网站建设推广熊掌号企业宣传片报价明细
  • 智能响应式网站钓鱼网站的主要危害
  • 网站建设竞争性磋商文件企业网站建设的三种方式
  • 做企业规划的网站做网站后台运营这个工作怎么样
  • 小说网站快速做排名企业推广策划书
  • 酒泉网站建设优化做的好的农产品网站有哪些
  • 本地电脑做服务器 建网站排名前十的小说
  • 塑胶原料 东莞网站建设抖音优化排名
  • 响应式旅游网站模板下载外贸软件
  • wordpress基础主题站公司名字大全推荐
  • 燕莎网站建设招聘网站收费标准对比图怎么做
  • 商城网站模板源码专业网站建设网站开发公司
  • jsp借书网站开发手机报价
  • 苏州专业网站建设设计域名网站模板
  • 网站开发时ie11的兼容网站风格设计视觉
  • 货物公司网站建设方案产品设计用什么软件好