package thread;
/**
* 产品仓库类
* @author wxg1022
*
*/
public class ProductList {
int index=0;
Product[] productlist=new Product[6];
public synchronized void push(Product product){
while(index==productlist.length){
try{
System.out.println("仓库已经满了,所以"+product.getProducedBy()+" 等等再生产");
//等待 wait();
//在这里等获取机会继续执行,并判断while(index==0)是否成立来执行
}catch(Exception e){
e.printStackTrace();
}
}
System.out.println("我来生产1个!");
//注意:notifyAll()以后,并没有退出,而是继续执行直到完成
productlist[index]=product;
index++;
//因为我们不确定有没有线程在wait(),所以我们既然生产了产品,就唤醒有可能等待的消费者,让他们醒来,准备消费
notifyAll();
System.out.println(" "+product.getProducedBy()+" sent a notifyAll()");
}
//pop用来让消费者取出产品
public synchronized Product pop(String consumerName){
//仓库空了
System.out.println(consumerName+"进来消费!");
while(index==0){
try{
System.out.println("没有可以消费的,所以"+consumerName+"等等再消费");
//等待 wait();
//在这里等获取机会继续执行,并判断while(index==0)是否成立来执行
}catch(Exception e){
e.printStackTrace();
}
}
System.out.print("我来消费1个!");
index--;
Product product=productlist[index];
product.consume(consumerName);
System.out.print("还剩"+index+"个产品,"+product.getConsumedBy()+ " 消费了:"+product);
//因为我们不能确定有没有线程在wait(),所以我们既然消费了产品,就唤醒有可能等待的生产者,让他们醒来,准备生产
notifyAll();
System.out.println(" "+consumerName+" send a notifyAll()");
return product;
}
}
package thread;
/**
* 产品类
* @author wxg1022
*
*/
public class Product {
int id;
private String producedBy="N/A";//谁生产的
private String consumedBy="N/A";//谁消费的
//构造函数指明生产者姓名
public Product(String producedBy) {
this.producedBy=producedBy;
// TODO Auto-generated constructor stub
}
//消费,需要指定消费者的名字
public void consume(String consumedBy){
this.consumedBy=consumedBy;
}
public String toString(){
return "产品[生产者="+producedBy+",消费者="+consumedBy+"]"; }
//以下是get/set方法
public String getProducedBy() {
return producedBy;
}
public void setProducedBy(String producedBy) {
this.producedBy = producedBy;
}
public String getConsumedBy() {
return consumedBy;
}
public void setConsumedBy(String consumedBy) {
this.consumedBy = consumedBy;
}
}
package thread;
/**
* 生产者类
* @author wxg1022
*
*/
public class Producer implements Runnable {
String name;
ProductList ps=null;
Producer(ProductList ps,String name){
this.ps=ps;
this.name=name;
}
@Override
public void run() {
// TODO Auto-generated method stub
while(true){
Product product=new Product(name);
ps.push(product);
try{
Thread.sleep((int)(Math.random()*2000));
}catch(Exception ee){
ee.printStackTrace();
}
}
}
}
package thread;
public class Consumer implements Runnable {
String name;
ProductList ps=null;
Consumer(ProductList ps,String name){
this.name=name;
this.ps=ps;
}
@Override
public void run() {
// TODO Auto-generated method stub
while(true){
ps.pop(name);
try{
Thread.sleep((int)(Math.random()*2000));
}catch(Exception ee){
ee.printStackTrace();
}
}
}
}
package thread;
public class ProducerCusumer {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
ProductList ps=new ProductList();
Producer px=new Producer(ps,"生产者X");
Producer py=new Producer(ps,"生产者Y");
Consumer ca=new Consumer(ps,"消费者A");
Consumer cb=new Consumer(ps,"消费者B");
Consumer cc=new Consumer(ps,"消费者C");
new Thread(px).start();
new Thread(py).start();
new Thread(ca).start();
new Thread(cb).start();
new Thread(cc).start();
}
}
运行结果如下:
我来生产1个!
生产者X sent a notifyAll()
我来生产1个!
生产者Y sent a notifyAll()
消费者A进来消费!
我来消费1个!还剩1个产品,消费者A 消费了:产品[生产者=生产者Y,消费者=消费者A] 消费者A send a notifyAll()
消费者B进来消费!
我来消费1个!还剩0个产品,消费者B 消费了:产品[生产者=生产者X,消费者=消费者B] 消费者B send a notifyAll()
消费者C进来消费!
没有可以消费的,所以消费者C等等再消费
我来生产1个!
生产者Y sent a notifyAll()
我来消费1个!还剩0个产品,消费者C 消费了:产品[生产者=生产者Y,消费者=消费者C] 消费者C send a notifyAll()
消费者A进来消费!
没有可以消费的,所以消费者A等等再消费
消费者B进来消费!
没有可以消费的,所以消费者B等等再消费
我来生产1个!
生产者Y sent a notifyAll()
我来消费1个!还剩0个产品,消费者B 消费了:产品[生产者=生产者Y,消费者=消费者B] 消费者B send a notifyAll()
没有可以消费的,所以消费者A等等再消费
我来生产1个!
生产者X sent a notifyAll()
我来消费1个!还剩0个产品,消费者A 消费了:产品[生产者=生产者X,消费者=消费者A] 消费者A send a notifyAll()
消费者A进来消费!
没有可以消费的,所以消费者A等等再消费
消费者B进来消费!
没有可以消费的,所以消费者B等等再消费
消费者C进来消费!
没有可以消费的,所以消费者C等等再消费
我来生产1个!
生产者X sent a notifyAll()
我来消费1个!还剩0个产品,消费者C 消费了:产品[生产者=生产者X,消费者=消费者C] 消费者C send a notifyAll()
没有可以消费的,所以消费者B等等再消费
我来生产1个!
生产者Y sent a notifyAll()
我来消费1个!还剩0个产品,消费者A 消费了:产品[生产者=生产者Y,消费者=消费者A] 消费者A send a notifyAll()
没有可以消费的,所以消费者B等等再消费
消费者C进来消费!
没有可以消费的,所以消费者C等等再消费
消费者A进来消费!
没有可以消费的,所以消费者A等等再消费
我来生产1个!
生产者Y sent a notifyAll()
我来消费1个!还剩0个产品,消费者A 消费了:产品[生产者=生产者Y,消费者=消费者A] 消费者A send a notifyAll()
没有可以消费的,所以消费者C等等再消费
没有可以消费的,所以消费者B等等再消费
我来生产1个!
生产者X sent a notifyAll()
我来消费1个!还剩0个产品,消费者B 消费了:产品[生产者=生产者X,消费者=消费者B] 消费者B send a notifyAll()
没有可以消费的,所以消费者C等等再消费
我来生产1个!
生产者Y sent a notifyAll()
我来消费1个!还剩0个产品,消费者C 消费了:产品[生产者=生产者Y,消费者=消费者C] 消费者C send a notifyAll()
消费者B进来消费!
没有可以消费的,所以消费者B等等再消费
我来生产1个!
生产者Y sent a notifyAll()
......................................
从以上运行的结果可以得出如下几点结论
1执行notifyAll()后,对于等待中的线程不能确地是谁能获取运行的机会。
2当执行wait()后,该线程后续的代码将会暂停执行,等获取执行机会后会接着执行,而不是重新执行。
3使用while而不是用if的原因
分享到:
相关推荐
JavaScript设计模式_hy5
【Jupyter Notebook】机器学习项目:微额借款用户人品预测
1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。
该项目为基于Android Studio开发的Bilibili安卓客户端设计源码,包含908个文件,其中包含471个PNG图片文件、220个Java源文件、187个XML布局文件、12个JPG图片文件、3个Gradle构建脚本文件、3个属性文件以及少量其他类型文件。该源码适用于学习Android应用开发,特别是对Bilibili客户端感兴趣的开发者。
DeepSeek 部署详细方式 DeepSeek 是一款功能强大的智能数据搜索和分析平台,其部署过程需要一定的技术背景和准备工作。以下是 DeepSeek 部署的详细步骤,旨在帮助用户顺利完成平台的搭建和配置。 一、准备工作 硬件要求: 服务器:具备足够的计算能力和存储空间,推荐配置高性能 CPU、大容量内存和 SSD 固态硬盘。 网络:确保服务器能够访问互联网,并且网络带宽足够支持数据传输和访问需求。 软件要求: 操作系统:支持 Linux(如 Ubuntu、CentOS 等)或 Windows Server。 数据库:MySQL 或 PostgreSQL 等关系型数据库,用于存储 DeepSeek 的数据和配置信息。 Python 环境:安装 Python 3.x 版本,并配置好相关的 Python 包管理工具(如 pip)。 域名和 SSL 证书: 域名:用于访问 DeepSeek 的 Web 界面。 SSL 证书:确保数据传输的安全性,推荐使用 Let's Encrypt 等免费 SSL 证书。 二、安装步骤 环境配置: 在服务器上安装并配置好操作系统、数据库和 Python
双标图与矩阵乘法演示实例
一种RBAC权限模型基于shiro权限框架的通用权限管理模板,_hy4
1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。
[RUST]模块化QQ机器人框架(BasedRICQ)_hy4
《机器学习:软件工程方法与实现》Methodandimplementationofmachinelearnin_hy4
【官方】计算机职业英语一级考试样卷.pdf 【官方】全国机等级考试二级笔试样卷:存取(Access)数据库程序设计.pdf 【官方】全国计算机等级考试二级笔试样卷:C++语言程序设计.pdf 【官方】全国计算机等级考试二级笔试样卷:C语言程序设计.pdf 【官方】全国机等级考试二级笔试样卷:德尔菲(Delphi)语言程序设计.pdf 【官方】全国机等级考试二级笔试样卷:Java语言程序设计.pdf 【官方】全国机等级考试二级笔试样卷:视觉基础语言程序设计.pdf 【官方】全国机等级考试二级笔试样卷:视讯FoxPro数据库程序设计.pdf 【官方】全国计算机等级考试三级笔试样卷:PC技术,pdf 【官方】全国计算机等级考试三级笔试样卷:网络技术.pdf 【官方】全国计算机等级考试三级笔试样卷:信息管理技术,pdf 【官方】全国计算机等级考试四级笔试样卷:软件测试工程师.pdf 【官方】全国计算机等级考试四级笔试样卷:数据库工程师,pdf 【官方】全国计算机等级考试四级笔试样卷:数据库技术,pdf 【官方】全国计算机等级考试四级笔试样卷:网络工程师.pdf
《MATLAB 小白修炼手册:从入门到实战》全面介绍 MATLAB。先阐述 MATLAB 在多领域的重要地位,随后深入讲解基础语法,包括变量、数据类型、运算符、控制语句等。详细介绍矩阵与数组这一核心结构的创建、运算和操作,以及常用数学、统计、绘图函数和文件操作。通过数据处理、数学建模、图像处理等案例,展示如何将知识用于实际。最后总结学习内容,鼓励深入探索,还推荐了学习资源与交流渠道,助力读者从新手成长为 MATLAB 实战高手 。
1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。
收录了「IT无知君」CSDN博客中涉及的Java项目源码,还有许多的开发工具类,都是我自己在用在不断维护的,需要请进!_hy4
【Vue+go】使用gin+gorm+jwt+casbin+vue组合实现的RBAC权限管理系统
该项目是针对.net课程的平时作业设计,包含96个文件,包括25个C#源代码文件、22个PNG图片文件、8个JSON数据文件、6个资源文件(.resx)、5个项目文件(.csproj)、5个配置文件(.config)、3个Markdown文档(.md)、3个图片文件(.jpg)、2个未分类文件(.v2和.suo)。这些资源共同构成了一个完整的课程作业集,旨在帮助学生巩固.net编程知识。
【go】用go语言实现消息中间件
【thinkphp】简单实现基于角色的权限控制,使用thinkphp5.0框架敏捷开发,实用的鉴权工具,rbac核心思路_pgj
微信公众号服务器开发脚手架_hy5
该平台是基于Vue框架构建的学科竞赛匹配与组建平台前端设计源码,包含44个文件,涵盖了18个Vue组件、11个TypeScript脚本、5个JSON配置文件、3个CSS样式文件、2个SVG图标、1个Git忽略规则、1个Markdown文档、1个HTML模板和1张JPG图片。项目以Vue、TypeScript、CSS和HTML为主要开发语言,旨在提供高效、易用的学科竞赛匹配与组建解决方案。