生产者与消费者模式简单介绍:
生产者线程生产物品,然后将物品放置在一个空缓冲区中供消费者线程消费。消费者线程从缓冲区中获得物品,然后释放缓冲区。当生产者线程生产物品时,如果没有空缓冲区可用,那么生产者线程必须等待消费者线程释放出一个空缓冲区。当消费者线程消费物品时,如果没有满的缓冲区,那么消费者线程将被阻塞,直到新的物品被生产出来
以示例来说明问题:
以下程序参考至: http://www.iteye.com/topic/256991
首先是产品类:
package consumerandproducter;
/**
* 单纯的产品类
* @author google
*
*/
public class Product {
private int productId=0;
public Product(int id){
this.productId=id;
}
public int getProductId() {
return productId;
}
public String toString(){
return "product "+productId;
}
}
再是仓库(缓冲区):
package consumerandproducter;
/**
* 模拟缓冲区,以栈为数据结构,先进后出
* @author google
*
*/
public class StoreHouse {
private int base=0;
private int top=0;
private Product[] products=new Product[10];
/**
* 入栈
* @param product
*/
public synchronized void push (Product product) {
while(top==products.length){
//当前的线程已经放弃对资源的占有,唤醒已经被wait的线程,唤醒的线程由JVM决定,不按优先级确定
notify();
try {
System.out.println("仓库已满,正在等待消费……");
wait();//此线程处于等待状态
} catch (Exception e) {
e.printStackTrace();
}
}
products[top]=product;
top++;
}
/**
* 出栈
* @return
*/
public synchronized Product pop(){
Product product=null;
while(top==base){
notify();
try {
System.out.println("仓库已空,正在等待生产……");
wait();
} catch (Exception e) {
e.printStackTrace();
}
}
top--;
product=products[top];
products[top]=null;
return product;
}
}
接着是消费者:
package consumerandproducter;
public class Consumer implements Runnable {
private String consumerName;
//保留有缓冲区对象的引用,以便消费产品
private StoreHouse storeHouse;
public Consumer(String consumerName, StoreHouse storeHouse) {
this.consumerName = consumerName;
this.storeHouse = storeHouse;
}
public void run() {
while(true){
System.out.println("消费者"+consumerName+"已经消费"+storeHouse.pop());
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public String getConsumerName() {
return consumerName;
}
public void setConsumerName(String consumerName) {
this.consumerName = consumerName;
}
}
然后是生产者:
package consumerandproducter;
/**
* 生产者类
* @author google
*
*/
public class Producter implements Runnable {
private String producterName;
// 保留有缓冲区对象的引用,以便将生产的产品放入缓冲区
private StoreHouse storeHouse;
public Producter(String producterName, StoreHouse storeHouse) {
this.producterName = producterName;
this.storeHouse = storeHouse;
}
public String getProducterName() {
return producterName;
}
public void setProducterName(String producterName) {
this.producterName = producterName;
}
public void producterProduct(){
//生产产品,并放入到仓库中
int i=0;
while(true){
i++;
Product product=new Product(i);
storeHouse.push(product);
System.out.println(producterName+"生产了");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
return;
}
}
}
public void run() {
producterProduct();
}
}
测试类:
package consumerandproducter;
import sun.security.krb5.internal.crypto.t;
public class Test {
public static void main(String[] args) {
StoreHouse storeHouse=new StoreHouse();
Producter producter=new Producter("生产者",storeHouse);
Consumer consumer=new Consumer("消费者",storeHouse);
Thread t1=new Thread(producter);
Thread t2=new Thread(consumer);
t1.start();
t2.start();
/**
* ~输出(随机抽取输出,每次测试的结果可能都有稍许不同):
*
生产者生产了
消费者消费者已经消费product 1
生产者生产了
消费者消费者已经消费product 2
生产者生产了
消费者消费者已经消费product 3
生产者生产了
消费者消费者已经消费product 4
...........
仓库已空,正在等待生产……
生产者生产了
生产者生产了
生产者生产了
生产者生产了
.........
仓库已满,正在等待消费……
消费者消费者已经消费product 14
消费者消费者已经消费product 13
消费者消费者已经消费product 12
消费者消费者已经消费product 11
消费者消费者已经消费product 10
......
*/
}
}
小结:
此问题主要是考察java间多线程通信与资源同步, 其中主要是对于notify与wait方法的使用上,还有对于线程间资源的共享,利用synchronized关键字,对共享资源的锁定,以达到线程同步的效果。
分享到:
相关推荐
在这个场景下,我们关注的是一个经典的并发编程模型——生产者消费者模式。该模式是多进程同步的一种典型应用,通过它我们可以高效地管理数据的生产和消费。 生产者消费者模式基于操作系统提供的信号量(Semaphore...
1. **生产者消费者模型**:一种用于解决多线程环境中资源分配和同步问题的经典设计模式。其中,“生产者”负责生成数据,“消费者”负责处理这些数据。 2. **多线程编程**:在单个程序中创建多个并发执行路径的技术...
总之,Java中的生产者-消费者模式是多线程编程中解决数据共享和同步问题的有效手段,通过合理利用`BlockingQueue`等并发工具类,我们可以构建高效、稳定的多线程应用。在开发过程中,了解和掌握这种模式有助于提高...
创建一个简单的生产者消费者模型,可以使用以下伪代码: ```java class Producer implements Runnable { private final BlockingQueue<String> queue; public Producer(BlockingQueue<String> queue) { this....
生产者消费者模式是一种经典的多线程同步问题解决方案,它源于现实世界中的生产流水线,用于描述生产者(Producer)和消费者(Consumer)之间的协作关系。在这个模式中,生产者负责生成产品并放入仓库,而消费者则从...
通过理解和掌握这些知识点,开发者能够有效地实现生产者-消费者模式,解决并发编程中的数据共享和协作问题。在实际项目中,这个模式常用于优化系统性能,尤其是在I/O密集型或计算密集型的应用中。
通过这个示例,我们不仅了解了生产者消费者模式,还学习了Java并发编程中`BlockingQueue`接口的使用,以及如何创建和管理线程。这是一个基础但非常实用的例子,有助于理解多线程环境中的同步和协作。在实际应用中,...
在Java中,可以使用`BlockingQueue`接口来实现生产者-消费者模式,它已经内置了线程安全的队列操作。生产者可以使用`offer()`方法添加元素,消费者则用`take()`方法取出元素,这两个方法会自动处理等待和唤醒操作。 ...
针对生产者-消费者问题,多线程同步方法提供了一种有效且可靠的解决方案。在本课程设计中,采用的是Linux环境下的C语言编程,利用了信号量(Semaphore)和互斥锁(Mutex)来实现线程间的同步和互斥访问。 - **信号...
线程池可以配合生产者消费者模式,例如通过提交任务到线程池来实现生产者,线程池中的工作线程充当消费者角色。 在使用生产者消费者模式时,需要注意以下几点: - **线程安全**:确保所有的操作都是线程安全的,...
综上所述,C#中的生产者消费者模式涉及线程同步、数据结构、异常处理等多个知识点,理解和熟练运用这些概念对于编写高效、可靠的并发程序至关重要。通过实践和优化,我们可以创建出能充分利用多核处理器能力、运行...
在多线程编程中,生产者消费者模型是一种常见的设计模式,用于解决线程间的通信和同步问题。在C#中,我们可以利用各种机制实现这样的队列。本篇将详细讲解如何在C#中构建一个生产消费者队列,以及它如何帮助优化线程...
总结来说,Linux多线程实现生产者消费者模式涵盖了多线程创建、线程同步与互斥、锁机制、条件变量以及线程屏障等核心知识点。这些知识点是Linux下进行高级多线程编程不可或缺的部分,对于理解现代操作系统中多任务...
生产者消费者模式是一种多线程或并发编程中的经典设计模式,它主要用于解决系统资源的高效利用和同步问题。在C++中实现生产者消费者模式,我们可以利用C++11及更高版本提供的线程库()、互斥量()、条件变量()等...
【生产者/消费者模式】是一种常见的并发编程和系统设计模式,它主要解决的是在多线程环境下,如何协调生产者和消费者之间的数据处理问题。在软件开发中,生产者通常是生成数据的一方,而消费者则是处理这些数据的...
"典型的多线程--生产和消费"这个主题,通常指的是生产者-消费者问题,这是一种经典的设计模式,用于解决如何在一个数据结构(如队列)中高效地存储和检索数据,同时避免生产者过于快速地生成数据而消费者无法及时...
然而,给定的标题“利用单线程完成的生产者与消费者程序”表明,这个程序是在单线程环境中实现的,这意味着没有并发线程,而是通过某种机制模拟了生产者和消费者的行为。 生产者-消费者模型通常用于处理数据流,...
总之,多生产者-多消费者模式是并发编程中的重要设计模式,通过合理利用同步机制,能够有效地解决线程间的通信问题,提高系统的并发性能。在Java中,我们可以借助`BlockingQueue`等工具实现这一模式,从而构建高效、...
6. **死锁与活锁**:在实现生产者消费者模式时,需要警惕死锁和活锁的情况。死锁是指两个或多个线程相互等待对方释放资源,导致无法继续执行。活锁则是线程不断地尝试获取资源但总是失败,从而陷入无限循环。正确的...