Java学习总结:29
线程间的经典操作案例——生产者与消费者案例
程序基本模型:
package Project.Study.Multithreading;class Message{private String title; //保存信息的标题private String content; //保存信息的内容public void setTitle(String title) {this.title = title;}public void setContent(String content) {this.content = content;}public String getTitle() {return title;}public String getContent() {return content;}
}
class Producer implements Runnable{ //定义生产者private Message msg=null;public Producer(Message msg){this.msg=msg;}@Overridepublic void run(){for (int x=0;x<50;x++){ //生产50次数据if(x%2==0){this.msg.setTitle("小关"); //定义title属性try {Thread.sleep(100); //延迟操作}catch (InterruptedException e){e.printStackTrace();}this.msg.setContent("学习Java");//设置content属性}else{this.msg.setTitle("小梁"); //设置title属性try {Thread.sleep(100); //延迟操作}catch (InterruptedException e){e.printStackTrace();}this.msg.setContent("学习python");//设置content属性}}}
}
class Consumer implements Runnable{private Message msg;public Consumer(Message msg){this.msg=msg;}@Overridepublic void run(){for(int x=0;x<50;x++){try{Thread.sleep(100);}catch (InterruptedException e){e.printStackTrace();}System.out.println(this.msg.getTitle()+"-->"+this.msg.getContent());}}
}
public class Test10 {public static void main(String []args){Message msg=new Message();new Thread(new Producer(msg)).start();new Thread(new Consumer(msg)).start();}
}
//结果:
//小梁-->学习Java
//小关-->学习python
//小梁-->学习Java
//小关-->学习python
//小梁-->学习Java
//小关-->学习python
//小梁-->学习Java
//小关-->学习python
//小梁-->学习Java
//(...)
本来上程序预期的输出结果是:小关–>学习Java,小梁–>学习python
但很明显出现了问题,设置的数据发生了错位、数据重复取出和重复设置。
解决数据错乱问题
数据错位完全是因为非同步的操作,所以应该使用同步处理。
例:加入同步,解决数据错乱问题
package Project.Study.Multithreading;class Message2{private String title; //保存信息的标题private String content; //保存信息的内容public synchronized void set(String title,String content){this.title=title;try{Thread.sleep(100);}catch(InterruptedException e){e.printStackTrace();}this.content=content;}public synchronized void get(){try{Thread.sleep(100);}catch (InterruptedException e){e.printStackTrace();}System.out.println(this.title+"-->"+this.content);}
}
class Producer2 implements Runnable{private Message2 meg=null;public Producer2(Message2 msg){this.meg=msg;}@Overridepublic void run(){for(int x=0;x<20;x++){if(x%2==0){this.meg.set("小关","学习Java");}else{this.meg.set("小梁","学习Python");}}}
}
class Consumer2 implements Runnable{private Message2 msg=null;public Consumer2(Message2 msg){this.msg=msg;}@Overridepublic void run(){for (int x=0;x<20;x++){this.msg.get();}}
}
public class Test11 {public static void main(String []args)throws Exception{Message2 msg=new Message2();new Thread(new Producer2(msg)).start();new Thread(new Consumer2(msg)).start();}
}
//结果:
//小梁-->学习Python
//小梁-->学习Python
//小梁-->学习Python
//小梁-->学习Python
//(...)
上程序解决了数据错位问题,但还是有重复取出和重复设置的问题。
解决数据重复问题
Object类对多线程的支持
No. | 方法 | 类型 | 描述 |
---|---|---|---|
1 | public final void wait() throws InterruptedException | 普通 | 线程的等待 |
2 | public final void notify() | 普通 | 唤醒第一个等待线程 |
3 | public final void notifyAll() | 普通 | 唤醒全部等待线程 |
一般来说,所有等待的线程会按照顺序进行排列。
如果使用了notify()方法,则会唤醒第一个等待的线程执行;
如果使用了notifyAll()方法,则会唤醒所有的等待线程,哪个线程的优先级高,哪个线程就有可能先执行。
例:
package Project.Study.Multithreading;class Message3{private String title;private String content;private boolean flag=true;//flag==true:表示可以生产,但是不能拿走//flag==false:表示可以取走,但是不能生产public synchronized void set(String title,String content){if(this.flag==false){try {super.wait(); //等待}catch (InterruptedException e){e.printStackTrace();}}this.title=title;try {Thread.sleep(100);}catch (InterruptedException e){e.printStackTrace();}this.content=content;this.flag=false; //已经生产完成,修改标志位super.notify(); //唤醒等待线程}public synchronized void get(){if (this.flag==true){ //未生产,不能取走try { super.wait(); //等待}catch (InterruptedException e){e.printStackTrace();}}try {Thread.sleep(100);}catch (InterruptedException e){e.printStackTrace();}System.out.println(this.title+"-->"+this.content);this.flag=true; //已经取走了,可以继续生产super.notify(); //唤醒等待线程}
}
class Producer3 implements Runnable{private Message3 meg;public Producer3(Message3 msg){this.meg=msg;}@Overridepublic void run(){for(int x=0;x<10;x++){if(x%2==0){this.meg.set("小关","学习Java");}else{this.meg.set("小梁","学习Python");}}}
}
class Consumer3 implements Runnable{private Message3 msg;public Consumer3(Message3 msg){this.msg=msg;}@Overridepublic void run(){for (int x=0;x<10;x++){this.msg.get();}}
}public class Test12 {public static void main(String []args){Message3 msg=new Message3();new Thread(new Producer3(msg)).start();new Thread(new Consumer3(msg)).start();}
}
//结果:
//小关-->学习Java
//小梁-->学习Python
//小关-->学习Java
//小梁-->学习Python
//小关-->学习Java
//小梁-->学习Python
//小关-->学习Java
//小梁-->学习Python
//小关-->学习Java
//小梁-->学习Python
上程序解决了数据错位、数据重复取出和重复设置问题。
提示:
sleep()和wait()的区别:
1.sleep()是Thread类定义的static方法,表示线程休眠,将执行机会给其他线程,但是监控状态依然保持,会自动恢复;
2.wait()是Object类定义的方法,表示线程等待,一直到执行了notify()或notifyAll()后才结束等待。
相关文章:

Blender终极角色创造:从初学者到专业人士
Ultimate character creation in Blender: From beginner to pro 流派:电子学习| MP4 |视频:h264,1280720 |音频:AAC,48.0 KHz 语言:英语中英文字幕(根据原英文字幕机译更准确) |大小解压后:24.8 GB 含建模参考图 |时长…

2022-2028年中国离心机行业市场研究及前瞻分析报告
【报告类型】产业研究 【报告价格】4500起 【出版时间】即时更新(交付时间约3个工作日) 【发布机构】智研瞻产业研究院 【报告格式】PDF版 本报告介绍了中国离心机行业市场行业相关概述、中国离心机行业市场行业运行环境、分析了中国离心机行业市场…

Shell 十三问 的学习记录
在 BBS上看到了Shell十三问的帖子,由于比较就远了,怕以后再也找不到了,就把笔记贴过来了, 原帖地址: shell 十三问http://bbs.chinaunix.net/thread-2033675-1-1.html 贴出我做的笔记: <一>、为何叫做…

图解八大排序算法——我见过的最详细的讲解(转)
一、分类 1.内部排序和外部排序 内部排序:待排序记录存放在计算机随机存储器中(说简单点,就是内存)进行的排序过程。外部排序:待排序记录的数量很大,以致于内存不能一次容纳全部记录,所以在排…

UE4创建第一人称射击游戏学习教程 Unreal Engine 4: Create Your Own First-Person Shooter
UE4创建第一人称射击游戏学习教程本课程包含38节视频课,将逐步指导您完成以下主题: 云桥网络 平台获取课程! 如何创建6种可定制的武器(包括手枪、突击步枪、猎枪、狙击枪、榴弹发射器和火箭发射器) 如何制作基于命中扫描和投射的武器 如何制作第一人…

PS多形式的部分之间复制“笨办法”
PS剪切页面,有时候你可能会遇到这样的情况:设计改进,但是,我们要具有相同的切片。 在此假设,可以直接用于切割片。我们可以节省大量的时间,又分为片。 但是,人们一般不会在你的上跨片设计PSD在变…

Java学习总结:30
线程的生命周期 suspend()方法:暂时挂起线程; resume()方法:恢复挂起的线程; stop()方法:停止线程。 对于以上三个方法不推荐使用,它们已经被慢慢废除掉了,主要原因是这三个方法在使用时容易产…
SVN优化(一) SVN忽略maven项目的target
SVN优化(一) SVN忽略maven项目的target 一 eclipse刚开始导入的项目: 二 解决办法 方式一: 在项目代码路径,如: F:\xyx\sl 鼠标右键,“TortoiseSVN”-- >“Settings” -->"Subversion"-->"Global ignore pattern" 添加:target *.…

“WPF老矣,尚能饭否”—且说说WPF今生未来(上):担心
2019独角兽企业重金招聘Python工程师标准>>> 近日微软公布了最新的WPF路线图,一片热议;对于老牌控件提供商葡萄城来说,这是WPF系列控件一个重要的机遇,因此,Spread Studio for WPF产品做了一次重要更新&…

C语言新手写扫雷攻略3
界面绘制好后,雷数也布置了,接下来就是游戏的运行过程了,今天先不说具体过程,再来看看需要用到的辅助函数 先是简单的画红旗,鼠标右键的功能是画红旗,至此我们都是在使用函数自己绘图,效率是低&…

制作欧比旺·克诺比逼真的CG角色学习教程
艺术站-制作欧比旺克诺比逼真的Cg角色 大小解压后:4.98G 含课程素材文件 1920X1080 .mp4 语言:英语中英文字幕(根据原英文字幕机译更准确) 课程获取:制作欧比旺克诺比逼真的CG角色学习教程 信息: 欧比旺是我一直以来…

Java学习总结:31(StringBuffer类)
StringBuffer类 在Java中String类不适合使用于频繁修改字符串的操作上(因为其字符串常量一旦声明则不可改变,只能改变字符串对象,改变的是其内存地址的指向),所以我们可以使用StringBuffer类方便用户进行内容的修改。 例:观察Str…

c语言常用数据类型转换整理
你要发送原始数据流 还是 格式化输出? 如果是格式化 按原子说的 ,用sprintf / printf; 如果发送原始内存数据流, 可按下面发送, 发送 #define BYTE0(pointer) (*((char*)(&pointer)0)); #define BYTE1(pointer) (*((char…

2022-2028年中国老年旅游市场深度调研及开发战略研究报告
【报告类型】产业研究 【报告价格】4500起 【出版时间】即时更新(交付时间约3个工作日) 【发布机构】智研瞻产业研究院 【报告格式】PDF版 本报告介绍了中国老年旅游行业市场行业相关概述、中国老年旅游行业市场行业运行环境、分析了中国老年旅游行…

Andriod使用webview控件往APP里内嵌网页
1.布局文件片段:res-layout <WebView android:id"id/Toweb" android:layout_width"fill_parent" android:layout_height"fill_parent" /> 2.Java片段:src Overrideprotected void onCreate(Bundle savedInstance…

垃圾回收器ZGC应用分析总结
ZGC 是一款低延迟、高吞吐的垃圾回收器,由 Oracle 公司开发。它适用于大型、多核、内存容量较大的应用程序。ZGC 的设计目标是在最大限度地减少停顿时间的同时,为大型内存提供可伸缩性,并为生产部署提供高吞吐量和稳定性。它的目标是以不到 10 毫秒的暂停时间来控制 100MB 到 4TB 的内存。此外,ZGC 还致力于避免全局 JVM 暂停,从而提高系统的可用性。简单来说,它的设计目标是在不超过 10 毫秒的暂停时间内,尽可能地回收大量的堆内存。低延迟:ZGC 的主要目标是最小化 GC 暂停时间。

14个Java并发容器,你用过几个?
不考虑多线程并发的情况下,容器类一般使用ArrayList、HashMap等线程不安全的类,效率更高。在并发场景下,常会用到ConcurrentHashMap、ArrayBlockingQueue等线程安全的容器类,虽然牺牲了一些效率,但却得到了安全。上面提到的线程安全容器都在java.util.concurrent包下,这个包下并发容器不少,今天全部翻出来鼓捣一下。仅做简单介绍,后续再分别深入探索。ConcurrentHashMap:并发版HashMap。

MySQL主从复制(基于binlog日志方式)
主从复制,是用来建立一个和主数据库完全一样的数据库环境,称为从数据库;主数据库一般是准实时的业务数据库。主从复制的作用1.做数据的热备,作为后备数据库,主数据库服务器故障后,可切换到从数据库继续工作,避免数据丢失。2.架构的扩展。业务量越来越大,I/O访问频率过高,单机无法满足,此时做多库的存储,降低磁盘I/O访问的频率,提高单个机器的I/O性能。3.读写分离,使数据库能支撑更大的并发。a.从服务器可以执行查询工作(就是我们常说的读功能),降低主服务器压力;(主库写,从库读,降压)

RabbitMQ安装
windows上安装过程:https://blog.csdn.net/linsongbin1/article/details/80170567运行中给新建用户赋权限,如果界面创完用户忘给权限了可以用这个方法:https://blog.csdn.net/hello_world_php/article/details/83859767 备注:我的…

Complete C# Unity Game Developer 2D
你会学到什么 从头开始学习C#,一门强大的现代语言。没有编程经验是必要的。 在使用Unity游戏引擎方面变得优秀。 为游戏设计和游戏开发打下坚实的基础,这将有助于您构建自己的游戏。 了解面向对象编程在实践中如何工作。 创建可玩的游戏项目——对你的投…

玩转android自定义控件二——自定义索引栏listview
带索引栏的listview,在android开发非常普遍,方便用户进行字母索引,就像微信通讯录这样: 今天,我们就从零到一实现这个具有索引栏的listview. 怎么实现这个控件了,我们应当梳理出一个思路。 ①首先应当将字母…

172. 阶乘后的零
给定一个整数 n,返回 n! 结果尾数中零的数量。 示例 1: 输入: 3 输出: 0 解释: 3! 6, 尾数中没有零。示例 2: 输入: 5 输出: 1 解释: 5! 120, 尾数中有 1 个零.说明: 你算法的时间复杂度应为 O(log n) 。 话不多说,先上代码: class So…

Mysql函数group_concat、find_in_set 多值分隔字符字段进行数据库字段值翻译
Mysql函数group_concat、find_in_set进行数据库字段值翻译 场景 配方表:记录包含的原料 sources表示原料,字段值之间用逗号分隔 原料表:对应原料id和原料名称 现需要查询出的原料结果显示为原料名称,并以逗号分隔。可通过函数g…

网站速度优化-前端篇
2019独角兽企业重金招聘Python工程师标准>>> 页面中最好不要有js片段,合并多个js为一个js,并将js压缩 (百度搜索,有在线js压缩、解压缩工具),并放在文档底部页面中最好不要有css片段,…

HashMap总结
为什么用HashMap HashMap是一个Hash桶(数组链表),桶存储的内容是键值对(Key-value)映射HashMap采用了数组和链表的数据结构,能在查询和修改方便继承了数组的线性查找和链表的寻址修改HashMap是非synchronized,所以HashMap很快(哈哈哈)与HashT…

Blender与Substance painter制作三维手枪
你会学到: Blender和Substance painter的基础知识 建模 纹理制作 烘焙 Uv展开 Boolens和斜角修改器 如何制作游戏准备枪 课程获取:Blender与Substance painter制作三维手枪 – 云桥网络-CG技术学习平台 要求 Blender Substance painter 你好,我是3d艺术…

Java学习总结:32(Runtime类)
Runtime类 该类用于表示虚拟机(JVM)运行时的状态,每次启动JVM都对应一个Runtime实例,且只有一个实例,利用Runtime类可以启动新的进程或进行相关运行时环境的操作。此外,该类采用单例模式设计,对象不可以直接实例化。所…

转:查看系统是64位还是32位
1、getconf LONG_BIT or getconf WORD_BIT 例如: 2、file /bin/ls 例如: 查看linux的版本: 转载于:https://www.cnblogs.com/lei-lei/p/5029120.html

Redis问题——Error: 磁盘在使用中,或被另一个进程锁定。
Redis出于对数据保护,默认只能本地客户端连接。远程连接就会出现以上错误。如何解决这一问题,看下: server -A,PC-A, 修改server-A的redis.conf:注释掉本地绑定; bind 127.0.0.1 表示指定绑定本机IP&…

[转]C#索引器
索引器是一种特殊的类成员,它能够让对象以类似数组的方式来存取,使程序看起来更为直观,更容易编写。 1、索引器的定义 C#中的类成员可以是任意类型,包括数组和集合。当一个类包含了数组和集合成员时,索引器将大大简化对…