java之wait()、notify()实现非阻塞的生产者和消费者

一、对于wait()和notify()的解释

    void notify()Wakes up a single thread that is waiting on this object’s monitor.唤醒等待获取锁资源的单个线程void notifyAll()Wakes up all threads that are waiting on this object’s monitor.唤醒等待获取锁资源的所有线程void wait( )Causes the current thread to wait until another thread invokes the notify() method or the notifyAll( ) method for this object.释放出对象的锁资源,程序会阻塞在这里

 

 

 

 

 

 

二、使用wait()、notify()、notifyAll()应该要注意的地方

  1、wait( ),notify( ),notifyAll( )都不属于Thread类,属于Object基础类,每个对象都有wait( ),notify( ),notifyAll( ) 的功能,因为每个对象都有锁

   2、当需要调用wait( ),notify( ),notifyAll( )的时候,一定都要在synchronized里面,不然会报 IllegalMonitorStateException 异常,可以这样理解,在synchronized(object) {}里面的代码才能获取到对象的锁。


  3、while循环里而不是if语句下使用wait,这样,会在线程暂停恢复后都检查wait的条件,并在条件实际上并未改变的情况下处理唤醒通知

  4、调用obj.wait( )释放了obj的锁,程序就会阻塞在这里,如果后面被notify()或者notifyAll()方法呼唤醒了之后,那么程序会接着调用obj.wait()后面的程序

    5、notify()唤醒等待获取锁资源的单个线程,notifyAll( )唤醒等待获取锁资源的所有线程

  6、当调用obj.notify/notifyAll后,调用线程依旧持有obj锁,其它线程仍无法获得obj锁,直到调用线程退出synchronized块或者在原有的obj调用wait释放锁,其它的线程才能起来

 

 

 

 

 

三、使用wait()、notify()、notifyAll()实现非阻塞式的消费者和生产者

package wait;import java.util.PriorityQueue;public class WaitAndNofityTest {public static final int COUNT = 5;//优先队列,消费者在这个队列里面消耗数据,生产者在这个里面生产数据public PriorityQueue<Integer> queue = new PriorityQueue<Integer>(COUNT);public static void main(String[] args) {WaitAndNofityTest waitAndNofityTest = new WaitAndNofityTest();Cus cus = waitAndNofityTest.new Cus();Make make = waitAndNofityTest.new Make();make.start();cus.start();}//消费者线程类class Cus extends Thread {@Overridepublic void run() {System.out.println("Cus queue size is:" + queue.size());eatData();}public void eatData() {while (true) {synchronized (queue) {System.out.println("go to eatData method size is:" + queue.size());while (queue.size() == 0) {try {System.out.println("Cus start notify");queue.notify();System.out.println("Cus start wait");queue.wait();System.out.println("Cus wait after");} catch (InterruptedException e) {queue.notify();}}queue.poll();System.out.println("Cus eatData after size is:" + queue.size());}}}}//生产者线程类class Make extends Thread {@Overridepublic void run() {System.out.println("Make queue size is:" + queue.size());addData();}public void addData() {while (true) {synchronized (queue) {System.out.println("go to addData method size is:" + queue.size());while (queue.size() == COUNT) {try {System.out.println("Make start notify");queue.notify();System.out.println("Make start wait");queue.wait();System.out.println("Make wait after");} catch (InterruptedException e) {queue.notify();}}queue.offer(5);System.out.println("Cus addData after size is:" + queue.size());}}}}
}

 

 

 

 

四、部分运行结果

Cus addData after size is:5
go to addData method size is:5
Make start notify
Make start wait
Cus wait after
Cus eatData after size is:4
go to eatData method size is:4
Cus eatData after size is:3
go to eatData method size is:3
Cus eatData after size is:2
go to eatData method size is:2
Cus eatData after size is:1
go to eatData method size is:1
Cus eatData after size is:0
go to eatData method size is:0
Cus start notify
Cus start wait
Make wait after
Cus addData after size is:1
go to addData method size is:1
Cus addData after size is:2
go to addData method size is:2
Cus addData after size is:3
go to addData method size is:3
Cus addData after size is:4
go to addData method size is:4
Cus addData after size is:5
go to addData method size is:5
Make start notify
Make start wait
Cus wait after
Cus eatData after size is:4
go to eatData method size is:4
Cus eatData after size is:3
go to eatData method size is:3
Cus eatData after size is:2
go to eatData method size is:2
Cus eatData after size is:1
go to eatData method size is:1
Cus eatData after size is:0
go to eatData method size is:0
Cus start notify
Cus start wait
Make wait after
Cus addData after size is:1
go to addData method size is:1
Cus addData after size is:2
go to addData method size is:2
Cus addData after size is:3
go to addData method size is:3
Cus addData after size is:4
go to addData method size is:4
Cus addData after size is:5
go to addData method size is:5
Make start notify
Make start wait
Cus wait after
Cus eatData after size is:4
go to eatData method size is:4
Cus eatData after size is:3
go to eatData method size is:3
Cus eatData after size is:2
go to eatData method size is:2
Cus eatData after size is:1
go to eatData method siz

如果运行了不理解,你可以自己测试然后分析打印的数据,当然你也可以注释掉2个类里面的任意一个notify方法,然后看是什么效果,是不是和自己分析的结果一样,同样你也可以去掉第一类的wait方法试下,看执行notify方法后是synchronized执行完了呼唤其其它线程或则在调用wait方法之后释放锁后是否也会呼唤其线程?

 

 

 

五、用ArrayBlockingQueue实现阻塞式的生产者和消费者

官方API

package wait;import java.util.concurrent.ArrayBlockingQueue;public class BlockTest {private int COUNT = 5;private ArrayBlockingQueue<Integer> queue = new ArrayBlockingQueue<Integer>(COUNT);public static void main(String[] args)  {BlockTest test = new BlockTest();Make make = test.new Make();Cus cus = test.new Cus();make.start();cus.start();}class Cus extends Thread {@Overridepublic void run() {eatData();}private void eatData() {while (true) {try {queue.take();System.out.println("队列取一个元素,队列剩余"+queue.size() + "元素");} catch (InterruptedException e) {e.printStackTrace();}}}}class Make extends Thread {@Overridepublic void run() {addData();}private void addData() {while(true){try {queue.put(5);System.out.println("队列插入一个元素,队列剩余空间:" + (COUNT-queue.size()));} catch (InterruptedException e) {e.printStackTrace();}}}}
}

 

 

 

 

 

 

 

 

 

 

六、部分运行结果

队列取一个元素,队列剩余4元素
队列取一个元素,队列剩余3元素
队列取一个元素,队列剩余2元素
队列取一个元素,队列剩余1元素
队列取一个元素,队列剩余0元素
队列插入一个元素,队列剩余空间:4
队列插入一个元素,队列剩余空间:3
队列插入一个元素,队列剩余空间:2
队列插入一个元素,队列剩余空间:1
队列插入一个元素,队列剩余空间:0
队列取一个元素,队列剩余4元素
队列取一个元素,队列剩余3元素
队列取一个元素,队列剩余2元素
队列取一个元素,队列剩余1元素
队列取一个元素,队列剩余0元素
队列插入一个元素,队列剩余空间:4
队列插入一个元素,队列剩余空间:3
队列插入一个元素,队列剩余空间:2
队列插入一个元素,队列剩余空间:1
队列插入一个元素,队列剩余空间:0
队列取一个元素,队列剩余4元素
队列取一个元素,队列剩余3元素
队列取一个元素,队列剩余2元素
队列取一个元素,队列剩余1元素
队列取一个元素,队列剩余0元素
队列插入一个元素,队列剩余空间:4
队列插入一个元素,队列剩余空间:3
队列插入一个元素,队列剩余空间:2
队列插入一个元素,队列剩余空间:1
队列插入一个元素,队列剩余空间:0
队列取一个元素,队列剩余4元素
队列取一个元素,队列剩余3元素
队列取一个元素,队列剩余2元素
队列取一个元素,队列剩余1元素
队列取一个元素,队列剩余0元素
队列插入一个元素,队列剩余空间:4
队列插入一个元素,队列剩余空间:3
队列插入一个元素,队列剩余空间:2
队列插入一个元素,队列剩余空间:1
队列插入一个元素,队列剩余空间:0
队列取一个元素,队列剩余4元素
队列取一个元素,队列剩余3元素
队列取一个元素,队列剩余2元素
队列取一个元素,队列剩余1元素
队列取一个元素,队列剩余0元素
队列插入一个元素,队列剩余空间:4
队列插入一个元素,队列剩余空间:3
队列插入一个元素,队列剩余空间:2
队列插入一个元素,队列剩余空间:1
队列插入一个元素,队列剩余空间:0
队列取一个元素,队列剩余4元素
队列取一个元素,队列剩余3元素
队列取一个元素,队列剩余2元素
队列取一个元素,队列剩余1元素
队列取一个元素,队列剩余0元素
队列插入一个元素,队列剩余空间:4
队列插入一个元素,队列剩余空间:3
队列插入一个元素,队列剩余空间:2
队列插入一个元素,队列剩余空间:1
队列插入一个元素,队列剩余空间:0
队列取一个元素,队列剩余4元素
队列取一个元素,队列剩余3元素
队列取一个元素,队列剩余2元素
队列取一个元素,队列剩余1元素
队列取一个元素,队列剩余0元素
队列插入一个元素,队列剩余空间:4
队列插入一个元素,队列剩余空间:3
队列插入一个元素,队列剩余空间:2
队列插入一个元素,队列剩余空间:1
队列插入一个元素,队列剩余空间:0
队列取一个元素,队列剩余4元素

 

 

 

 

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/289670.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

大数据先行 传统金融转型需从体制上创新

经过几年发展&#xff0c;互联网金融成为金融行业一股鲜活的力量。同时&#xff0c;行业也意识到&#xff0c;这条鲶鱼不会在大众市场对银行构成威胁。日前&#xff0c;德勤的一份报告也指出&#xff0c;P2P的市场价值高达1800亿美元&#xff0c;但并没有在成本、风险和速度上对…

oracle存档模式,Oracle的备份和存档模式

Oracle的备份和存档模式在做硬件升级前必须要将数据库做一次全备份&#xff0c;以便在出现不可预料的情况下进行恢复&#xff0c;全备份的方法有多种&#xff0c;以下列举两种简单高效的逻辑备份和冷备份&#xff0c;在数据库可以宕机的条件下&#xff0c;推荐使用冷备份&#…

SVN安装和使用总结

SVN简介&#xff1a; 为什么要使用SVN&#xff1f; 程序员在编写程序的过程中&#xff0c;每个程序员都会生成很多不同的版本&#xff0c;这就需要程序员有效的管理代码&#xff0c;在需要的时候可以迅速&#xff0c;准确取出相应的版本。 Subversion是什么&#xff1f; 它是一…

从部署 httpd 入手,理清 k8s 配置中的 containerPort、port、nodePort、targetPort

注&#xff1a;文中各种内网、公网 IP 仅为示例&#xff0c;不保证所有 IP 都可以访问&#xff0c;且你的环境中 IP 可能不同。背景在上一篇文章 自己搭建一个k8s环境 中&#xff0c;我们一顿操作猛如虎&#xff0c;搭建出了由 1 个 master 和 1 个 worker 节点组成的 k8s 集群…

C#正则表达式判断输入的是不是数字

1.函数 public static bool IsFloat(string str){string regextext "^(-?\d)(\.\d)?$";Regex regex new Regex(regextext, RegexOptions.None);return regex.IsMatch(str.Trim());} 2.调用if (!IsFloat(textBox11.Text)){MessageBox.Show("应该是一个数字&q…

分享几个拉钩网的前端页面

http://c.lagou.com/allMarch/warmup/index.html?fromsinglemessage&isappinstalled0 http://c.lagou.com/careerism/invitation.html?fromgroupmessage&amp;isappinstalled0&scene4转载于:https://blog.51cto.com/snaile/1616398

Andorid之用ConditionVariable实现线程同步

一、学习ConditionVariable之前的复习 如果你不懂wait()、notify()怎么使用&#xff0c;最好先复习下我之前的这篇博客&#xff0c;怎么使用wait()、notify()实现生产者和消费者的关系 java之wait()、notify()实现非阻塞的生产者和消费者 二、看下ConditionVariable源代码实现…

360文件粉碎机_中山三乡资料文件销毁粉碎销毁资料文件公司一览表

中山三乡资料文件销毁粉碎销毁资料文件公司一览表安排搬运工作人员及运输车辆上门收取销毁物品&#xff0c;将需销毁的物品装上运输车辆&#xff0c;并进行拍照、车箱粘贴封条等工作。第五步&#xff1a;客户可安排工作人员&#xff0c;跟我公司销毁运输车辆一同前往我公司销毁…

Sonnedix收购意大利11.2MW光伏电站产品组合

2016年9月5日, 太阳能独立发电商Sonnedix宣布已经在意大利获得Trading Emissions 的11.2MW太阳能光伏电站产品组合&#xff0c;此交易预计将在2016年第四季度关闭。 该产品组合包括三个地面安装光伏电站: 阿布鲁佐的Basciano和Cupello、以及西西里岛的Librandello。 Sonnedix在…

oracle中行数少于1000,oracle中in的个数超过1000的解决办法

oracle中in的个数要是超过1000就会报错&#xff0c;那么我们可以把它拆成一节一节的&#xff1a;in(1,2) or in (3,4)StringUtils.defaultIfEmpty的命名空间是&#xff1a;import org.apache.commons.lang.StringUtils;private String getOracleSQLIn(List> ids, int count,…

SQL Server 2005更改当前数据库的所有者

语法 sp_changedbowner [ @loginame = ] login[ , [ @map= ] remap_alias_flag ] 参数 [ @loginame = ] login 当前数据库的新所有者的登录 ID。login 的数据类型为 sysn

Xamarin效果第十七篇之AR GIS

在前面几篇文章中简单玩耍了一下在线、离线加载高德地图和添加Mark;今天在原来的基础上再去玩玩AR GIS;来看看最终效果:1、先通过NuGet引用:Install-Package Esri.ArcGISRuntime.ARToolkit.Forms -Version 100.13.02、在AndroidManifest.xml中配置:<application android:lab…

maven 多项目搭建

参考http://www.cnblogs.com/xdp-gacl/p/3498271.html 。 1.什么是maven maven是基于项目对象模型(POM)&#xff0c;是跨平台的管理工具&#xff0c;主要服务于java平台的项目构建&#xff0c;依赖管理和项目信息管理。 2.maven的好处 Maven中使用约定&#xff0c;约定java源代…

IOS之学习笔记四(类的实现和对象和id)

1、简单构建类和对象和id使用的测试代码如下 Person.h #ifndef Person_h #define Person_h#import <Foundation/Foundation.h> interface Person : NSObject {NSString* _name;int _age; } -(void)setName:(NSString *)name addAge:(int)age; -(void)say:(NSString *)c…

rog live service是什么_双11手机怎么买?ROG游戏手机3“独一份”体验,值得剁手...

对于追求极致的手游党来说&#xff0c;手机设备性能的强悍极为重要&#xff0c;毕竟时刻影响着流畅性与游戏体验。纵观当下手机厂商推出的游戏手机来看&#xff0c;ROG游戏手机3可以说是目前性能最强的游戏手机&#xff0c;在下半年发布的多款旗舰均没能领先过ROG。这也证明了我…

SQL Server 2005将某些数据库行为设置为与指定的 SQL Server 版本兼容

语法 sp_dbcmptlevel [ [ dbname ] name ] [ , [ new_cmptlevel ] version ]参数 [ dbname ] name要为其更改兼容级别的数据库的名称。数据库名称必须符合标识符的规则。name 的数据类型为 sysname&#xff0c;默认值为 NULL。 [ new_cmptlevel ] version数据库要与之兼容的…

oracle 优化分组 sql语句,Oracle SQL语句之常见优化方法 五

0、低效SQL语句查询:SELECT b.sql_text, --SQL內容a.sid,a.serial#,a.status,a.machine, --哪台机器運行的SQLa.username, --用戶a.module, --運行方式a.action, --Responsibilityc.opname,c.target,c.message,c.sofar totalwork * 100, --工作執行了百分之多少c.elapsed_secon…

我将 20 年前开发的操作系统迁移到 .NET 6,竟然成功了!

作者 | Scott Hanselman译者 | 弯月早在2001年&#xff0c;我用C#为学校的一门300系列的操作系统课程编写了一个微型虚拟操作系统&#xff0c;后来在2002年将其移植到了VB.NET。这些都是在.NET Core出现之前的代码&#xff0c;基于Windows早期的.NET 1.1或2.0。五年前&#xff…

bzoj2132: 圈地计划

要分成两坨对吧。。 所以显然最小割 但是不兹辞啊。。 最小割是最小的啊 求最大费用怎么玩啊 那咱们就把所有费用都加起来&#xff0c;减掉一个最小的呗 但是两个属于不同集合的点贡献的价值是负的啊 网络流怎么跑负的啊 那咱就交换一下呗 原图是二分图啊&#xff0c;把另一部分…

BEVFormerV2 论文阅读

论文链接 BEVFormer v2: Adapting Modern Image Backbones to Bird’s-Eye-View Recognition via Perspective Supervision 0. Abstract 提出了一种新颖的 BEV 检测器&#xff0c;具有透视监督&#xff0c;收敛速度更快&#xff0c;更适合现代图像基础架构优先考虑通过引入透…