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的原因
分享到:
相关推荐
(1)创建生产者和消费者线程 在Windows2000环境下,创建一个控制台进程,在此进程中创建n个线程来模拟生产者或者消费者。这些线程的信息由本程序定义的“测试用例文件”中予以指定。 该文件的格式和含义如下: 3 1 ...
生产者和消费者线程都需要有自己的业务逻辑,这可以通过重写`run()`方法实现。 2. **共享资源**:在生产者-消费者模型中,通常会有一个固定大小的缓冲区作为共享资源。可以使用数组或链表实现,但需要注意的是,当...
### 编程模拟生产者和消费者问题 #### 实验背景及目标 在现代操作系统中,进程间的同步是非常重要的概念之一。特别是对于共享资源的管理,如何有效地协调多个进程的访问,确保系统的稳定性和效率,是操作系统设计...
6. **线程间的通信**:在生产者和消费者之间,可能还需要额外的信号和槽(signal and slot)来协调他们的操作,比如当缓冲区满时通知生产者停止生产,或者当缓冲区空时通知消费者暂停消费。 通过以上步骤,我们可以...
"生产者消费者问题"和"读写者问题"是经典的并发控制问题,通过使用信号量机制可以有效地解决这些问题。下面将详细阐述这两个问题以及如何在Linux环境下用C语言实现。 首先,我们来看“生产者消费者问题”。这个问题...
在"生产者和消费者问题.txt"文件中,可能包含了使用`BlockingQueue`实现生产者消费者问题的Java代码示例,包括如何创建队列,以及生产者和消费者线程如何交互。而"哲学家就餐问题.txt"文件可能展示了如何用Java的...
在这个“java IBM MQ 7.5.0 生产者和消费者实例”中,我们将探讨如何使用Java编程语言与IBM MQ 7.5.0版本进行交互,创建生产者和消费者应用。 1. **IBM MQ安装与配置**: 在开始编程之前,首先需要在本地或服务器...
### 操作系统上机实验报告:进程同步和通信——生产者和消费者问题模拟 #### 一、实验目的 本次实验的主要目的是让学生通过调试、修改、运行一个模拟程序,加深对进程概念的理解,熟悉同步和通信的过程,掌握进程...
生产者和消费者问题是这样的:想象有一个缓冲区,生产者线程负责生产产品并放入缓冲区,而消费者线程则负责从缓冲区取出并消费产品。问题的核心在于,当缓冲区满时,生产者必须等待消费者消费一部分产品才能继续生产...
生产者负责生产产品,而消费者负责消费产品。生产者和消费者之间需要同步,以避免冲突。使用PV操作同步机构可以实现生产者和消费者之间的同步。 在实验中,需要模拟生产者和消费者的并发执行,并使用PV操作来实现...
《生产者-消费者问题在C++中的实现》 生产者-消费者问题是多线程编程中的经典案例,它展示了如何在并发环境中实现线程间的同步与互斥。在本项目中,我们将探讨这个问题,并以C++语言为基础,创建一个在Windows 2000...
创建一个简单的生产者消费者模型,可以使用以下伪代码: ```java class Producer implements Runnable { private final BlockingQueue<String> queue; public Producer(BlockingQueue<String> queue) { this....
5. 在生产者和消费者完成操作后,通过V操作增加count,唤醒可能被阻塞的进程。 接下来是读进程具有优先权的读者-写者问题。在此问题中,多个读者可以同时读取数据,但只有一个写者可以修改数据,且写者在写入时不能...
在Kafka中,生产者负责生成消息并将其发布到主题(topics),而消费者则订阅这些主题并消费其中的消息。本篇文章将深入探讨如何在Java环境中使用IDEA,通过Maven构建工具来实现Kafka的生产者和消费者。 首先,我们...
生产者消费者问题解决方案 生产者消费者问题是计算机科学中的一种经典问题,...该解决方案提供了一个完整的生产者消费者问题的解决方案,使用信号量机制来实现线程之间的同步,解决了生产者和消费者之间的协作问题。