Java线程:并发协作-生产者消费者模型

实际上,准确说应该是“生产者-消费者-仓储”模型,离开了仓储,生产者消费者模型就显得没有说服力了。

对于此模型,应该明确一下几点:

1、生产者仅仅在仓储未满时候生产,仓满则停止生产。

2、消费者仅仅在仓储有产品时候才能消费,仓空则等待。

3、当消费者发现仓储没产品可消费时候会通知生产者生产。

4、生产者在生产出可消费产品时候,应该通知等待的消费者去消费。

此模型将要结合java.lang.Object的wait与notify、notifyAll方法来实现以上的需求。这是非常重要的。

/**
* Java线程:并发协作-生产者消费者模型
*
* @author leizhimin
*/
public class Test {
         public static void main(String[] args) {
                 Godown godown = new Godown(30);
                 Consumer c1 = new Consumer(50, godown);
                 Consumer c2 = new Consumer(20, godown);
                 Consumer c3 = new Consumer(30, godown);
                 Producer p1 = new Producer(10, godown);
                 Producer p2 = new Producer(10, godown);
                 Producer p3 = new Producer(10, godown);
                 Producer p4 = new Producer(10, godown);
                 Producer p5 = new Producer(10, godown);
                 Producer p6 = new Producer(10, godown);
                 Producer p7 = new Producer(80, godown);
                 c1.start();
                 c2.start();
                 c3.start();
                 p1.start();
                 p2.start();
                 p3.start();
                 p4.start();
                 p5.start();
                 p6.start();
                 p7.start();
         }
}
/**
* 仓库
*/
class Godown {
         public static final int max_size = 100; //最大库存量
         public int curnum; //当前库存量
         Godown() {
         }
         Godown(int curnum) {
                 this.curnum = curnum;
         }
         /**
          * 生产指定数量的产品
          *
          * @param neednum
          */
         public synchronized void produce(int neednum) {
                 //测试是否需要生产
                 while (neednum + curnum > max_size) {
                         System.out.println("要生产的产品数量" + neednum + "超过剩余库存量" + (max_size - curnum) + ",暂时不能执行生产任务!");
                         try {
                                 //当前的生产线程等待
                                 wait();
                         } catch (InterruptedException e) {
                                 e.printStackTrace();
                         }
                 }
                 //满足生产条件,则进行生产,这里简单的更改当前库存量
                 curnum += neednum;
                 System.out.println("已经生产了" + neednum + "个产品,现仓储量为" + curnum);
                 //唤醒在此对象监视器上等待的所有线程
                 notifyAll();
         }
         /**
          * 消费指定数量的产品
          *
          * @param neednum
          */
         public synchronized void consume(int neednum) {
                 //测试是否可消费
                 while (curnum < neednum) {
                         try {
                                 //当前的生产线程等待
                                 wait();
                         } catch (InterruptedException e) {
                                 e.printStackTrace();
                         }
                 }
                 //满足消费条件,则进行消费,这里简单的更改当前库存量
                 curnum -= neednum;
                 System.out.println("已经消费了" + neednum + "个产品,现仓储量为" + curnum);
                 //唤醒在此对象监视器上等待的所有线程
                 notifyAll();
         }
}
/**
* 生产者
*/
class Producer extends Thread {
         private int neednum; //生产产品的数量
         private Godown godown; //仓库
         Producer(int neednum, Godown godown) {
                 this.neednum = neednum;
                 this.godown = godown;
         }
         public void run() {
                 //生产指定数量的产品
                 godown.produce(neednum);
         }
}
/**
* 消费者
*/
class Consumer extends Thread {
         private int neednum; //生产产品的数量
         private Godown godown; //仓库
         Consumer(int neednum, Godown godown) {
                 this.neednum = neednum;
                 this.godown = godown;
         }
         public void run() {
                 //消费指定数量的产品
                 godown.consume(neednum);
         }
}

时间: 2024-12-10 23:37:55

Java线程:并发协作-生产者消费者模型的相关文章

如何在 Java 中正确使用 wait, notify 和 notifyAll – 以生产者消费者模型为例

wait, notify 和 notifyAll,这些在多线程中被经常用到的保留关键字,在实际开发的时候很多时候却并没有被大家重视.本文对这些关键字的使用进行了描述. 在 Java 中可以用 wait.notify 和 notifyAll 来实现线程间的通信..举个例子,如果你的Java程序中有两个线程--即生产者和消费者,那么生产者可以通知消费者,让消费者开始消耗数据,因为队列缓冲区中有内容待消费(不为空).相应的,消费者可以通知生产者可以开始生成更多的数据,因为当它消耗掉某些数据后缓冲区不再

使用阻塞队列实现生产者-消费者模型

1.生产者-消费者问题 生产者消费者问题也称作有界缓冲区(bounded-buffer)问题, 是操作系统中一个经典的线程同步问题,问题描述如下: 生产者在生产产品提供给若干个消费者去消费,为了使生产者和消费者能并发执行,在两者之间设置一个具有多个缓冲区,生产者将它生产的产品放入缓冲区中,消费者可以从缓冲区中取走产品进行消费,两个进程共享一个公共的固定大小的缓冲区. 显然生产者和消费者之间必须保持同步,即不允许消费者到一个空的缓冲区中取产品,也不允许生产者向一个已经放入产品的缓冲区中再次投放产品

Linux线程编程之生产者消费者问题

前言 本文基于顺序循环队列,给出Linux生产者/消费者问题的多线程示例,并讨论编程时需要注意的事项.文中涉及的代码运行环境如下: 本文假定读者已具备线程同步的基础知识. 一  顺序表循环队列 1.1 顺序循环队列定义 队列是一种运算受限的先进先出线性表,仅允许在队尾插入(入队),在队首删除(出队).新元素入队后成为新的队尾元素,元素出队后其后继元素就成为队首元素. 队列的顺序存储结构使用一个数组和两个整型变量实现,其结构如下: 1 struct Queue{ 2     ElemType el

【Python之旅】第六篇(五):生产者消费者模型实现多线程异步交互

 虽然标题是"生产者消费者模型实现多线程异步交互",但这里要说的应该还包括Python的消息队列,因为这里多线程异步交互是通过Python的消息队列来实现的,因此主要内容如下: 1 2 3 4 1.生产者消费者模型:厨师做包子与顾客吃包子 2.Python的消息队列 3.利用消息队列实现Python多线程异步交互 4.再谈耦合度的问题 1.生产者消费者模型     通过厨师做包子与顾客吃包子来引出生产者消费者模型,如下图:     这里,厨师相当于生产者,顾客相当于消费者,顾客吃包子,

Qt之线程同步(生产者消费者模式 - QWaitCondition)

简述 生产者将数据写入缓冲区,直到它到达缓冲区的末尾,这时,它从开始位置重新启动,覆盖现有数据.消费者线程读取数据并将其写入标准错误. Wait condition(等待条件)比单独使用 mutex(互斥量)有一个更高级的并发性,如果缓冲区的访问由一个 QMutex 把守,当生产者线程访问缓冲区时,消费者线程将无法访问.然而,两个线程同时访问不同的缓冲区是没有害处的. 示例包含两个类:Producer 和 Consumer,均继承自 QThread.循环缓冲区用于两个类之间的沟通,同步工具用于保

Qt之线程同步(生产者消费者模式 - QSemaphore)

简述 生产者将数据写入缓冲区,直到它到达缓冲区的末尾,此时,它将从开始位置重新启动,覆盖现有数据.消费者线程读取数据并将其写入标准错误. Semaphore(信号量) 比 mutex(互斥量)有一个更高级的并发性.如果缓冲区的访问由一个 QMutex 把守,当生产者线程访问缓冲区时,消费者线程将无法访问.然而,有两个线程同一时间访问不同的缓冲区是没有害处的. 示例包括两个类:Producer 和 Consumer,均继承自 QThread.循环缓冲区用于这两个类之间的沟通,信号量用于保护全局变量

JAVA线程中的生产者和消费者问题

生产者消费者问题是研究多线程时绕不开的问题,描述的是有一块生产者和消费者共享的有界缓冲区,生产者往缓冲区放入产品,消费者从缓冲区取走产品,这个过程可以无休止的执行,不能因缓冲区满生产者放不进产品而终止,也不能因缓冲区空消费者无产品可取而终止. 解决生产者消费者问题的方法有两种,一种是采用某种机制保持生产者和消费者之间的同步,一种是在生产者和消费者之间建立一个管道.前一种有较高的效率并且可控制性较好,比较常用,后一种由于管道缓冲区不易控制及被传输数据对象不易封装等原因,比较少用. 同步问题的核心在

聊聊并发:生产者消费者模式

在并发编程中使用生产者和消费者模式能够解决绝大多数并发问题.该模式通过平衡生产线程和消费线程的工作能力来提高程序的整体处理数据的速度. 为什么要使用生产者和消费者模式 在线程世界里,生产者就是生产数据的线程,消费者就是消费数据的线程.在多线程开发当中,如果生产者处理速度很快,而消费者处理速度很慢,那么生产者就必须等待消费者处理完,才能继续生产数据.同样的道理,如果消费者的处理能力大于生产者,那么消费者就必须等待生产者.为了解决这个问题于是引入了生产者和消费者模式. 什么是生产者消费者模式 生产者

浅谈Java线程并发知识点_java

发布:一个对象是使它能够被当前范围之外的代码所引用: 常见形式:将对象的的引用存储到公共静态域:非私有方法中返回引用:发布内部类实例,包含引用. 逃逸:在对象尚未准备好时就将其发布. 不要让this引用在构造函数中逸出.例,在构造函数中启动线程,线程会包含对象的引用. 同步容器:对容器的所有状态进行穿行访问,Vector.Hashtable,Cllections.synchronizedMap|List 并发容器:ConcurrentHashMap,CopyOnWriteArrayList,Co