这是个线程同步的经典例子,源代码如下:

  1. <span style="font-size:16px;">package demo.thread;
  2. /**
  3. *经典生产者与消费者问题:生产者不断的往仓库中存放产品,消费者从仓库中消费产品。
  4. *其中生产者和消费者都可以有若干个。仓库容量有限,库满时不能存放,库空时不能取产品
  5. */
  6. public class ProducersAndConsumers {
  7. public static void main(String[] args) {
  8. Storage storage = new Storage();
  9. Thread consumer = new Thread(new Consumer(storage));
  10. consumer.setName("消费者");
  11. Thread producer = new Thread(new Producer(storage));
  12. producer.setName("生产者");
  13. consumer.start();
  14. producer.start();
  15. }
  16. }
  17. /**
  18. * 消费者
  19. */
  20. class Consumer implements Runnable {
  21. private Storage storage;
  22. public Consumer(Storage storage) {
  23. this.storage = storage;
  24. }
  25. @Override
  26. public void run() {
  27. storage.pop();
  28. }
  29. }
  30. /**
  31. * 生产者
  32. */
  33. class Producer implements Runnable {
  34. private Storage storage;
  35. public Producer(Storage storage) {
  36. this.storage = storage;
  37. }
  38. @Override
  39. public void run() {
  40. Product product = new Product("090505105", "电话");
  41. storage.push(product);
  42. }
  43. }
  44. /**
  45. * 产品类
  46. */
  47. class Product {
  48. private String id;// 产品id
  49. private String name;// 产品名称
  50. public Product(String id, String name) {
  51. this.id = id;
  52. this.name = name;
  53. }
  54. @Override
  55. public String toString() {
  56. return "(产品ID:" + id + " 产品名称:" + name + ")";
  57. }
  58. public String getId() {
  59. return id;
  60. }
  61. public void setId(String id) {
  62. this.id = id;
  63. }
  64. public String getName() {
  65. return name;
  66. }
  67. public void setName(String name) {
  68. this.name = name;
  69. }
  70. }
  71. /**
  72. *仓库
  73. */
  74. class Storage {
  75. // 仓库容量为10
  76. private Product[] products = new Product[10];
  77. private int top = 0;
  78. // 生产者往仓库中放入产品
  79. public synchronized void push(Product product) {
  80. while (top == products.length) {
  81. try {
  82. wait();//仓库已满,等待
  83. } catch (InterruptedException e) {
  84. // TODO Auto-generated catch block
  85. e.printStackTrace();
  86. }
  87. }
  88. //把产品放入仓库
  89. products[top++] = product;
  90. System.out.println(Thread.currentThread().getName() + " 生产了产品"
  91. + product);
  92. notifyAll();//唤醒等待线程
  93. }
  94. // 消费者从仓库中取出产品
  95. public synchronized Product pop() {
  96. while (top == 0) {
  97. try {
  98. wait();//仓库空,等待
  99. } catch (InterruptedException e) {
  100. // TODO Auto-generated catch block
  101. e.printStackTrace();
  102. }
  103. }
  104. //从仓库中取产品
  105. --top;
  106. Product p = new Product(products[top].getId(), products[top].getName());
  107. products[top] = null;
  108. System.out.println(Thread.currentThread().getName() + " 消费了产品" + p);
  109. notifyAll();//唤醒等待线程
  110. return p;
  111. }
  112. }
  113. </span>

运行结果:

生产者 生产了产品(产品ID:090505105 产品名称:电话)
消费者 消费了产品(产品ID:090505105 产品名称:电话)

java多线程总结六:经典生产者消费者问题实现的更多相关文章

  1. Java 多线程学习笔记:生产者消费者问题

    前言:最近在学习Java多线程,看到ImportNew网上有网友翻译的一篇文章<阻塞队列实现生产者消费者模式>.在文中,使用的是Java的concurrent包中的阻塞队列来实现.在看完后 ...

  2. java 多线程并发系列之 生产者消费者模式的两种实现

    在并发编程中使用生产者和消费者模式能够解决绝大多数并发问题.该模式通过平衡生产线程和消费线程的工作能力来提高程序的整体处理数据的速度. 为什么要使用生产者和消费者模式 在线程世界里,生产者就是生产数据 ...

  3. java多线程系列15 设计模式 生产者 - 消费者模式

    生产者-消费者 生产者消费者模式是一个非常经典的多线程模式,比如我们用到的Mq就是其中一种具体实现 在该模式中 通常会有2类线程,消费者线程和生产者线程 生产者提交用户请求 消费者负责处理生产者提交的 ...

  4. Java多线程之并发协作生产者消费者设计模式

    两个线程一个生产者个一个消费者 需求情景 两个线程,一个负责生产,一个负责消费,生产者生产一个,消费者消费一个 涉及问题 同步问题:如何保证同一资源被多个线程并发访问时的完整性.常用的同步方法是采用标 ...

  5. Java多线程—阻塞队列和生产者-消费者模式

    阻塞队列支持生产者-消费者这种设计模式.该模式将“找出需要完成的工作”与“执行工作”这两个过程分离开来,并把工作项放入一个“待完成“列表中以便在随后处理,而不是找出后立即处理.生产者-消费者模式能简化 ...

  6. “全栈2019”Java多线程第六章:中断线程interrupt()方法详解

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...

  7. Java阻塞队列(BlockingQueue)实现 生产者/消费者 示例

    Java阻塞队列(BlockingQueue)实现 生产者/消费者 示例 本文由 TonySpark 翻译自 Javarevisited.转载请参见文章末尾的要求. Java.util.concurr ...

  8. 【Java并发编程】:生产者—消费者模型

    生产者消费者问题是线程模型中的经典问题:生产者和消费者在同一时间段内共用同一存储空间,生产者向空间里生产数据,而消费者取走数据. 这里实现如下情况的生产--消费模型: 生产者不断交替地生产两组数据“姓 ...

  9. java线程之多个生产者消费者

    温故一下上一节所学习的生产者消费者代码: 两个线程时: 通过标志位flag的if判断和同步函数互斥较好解决两个线程,一个生产者.一个消费者交替执行的功能 类名:ProducterConsumerDem ...

随机推荐

  1. 【C++深入浅出】设计模式学习之观察者模式

    前言 前两天学习了weak_ptr以后还是不甚明了,一则需要实际应用去锤炼,二来就是不懂观察者模式. 正文 观察者模式又叫发布-订阅模式,定义了一种一对多的依赖关系,让多个观察者对象同时监听某一主题对 ...

  2. .NET世界各成员之间的关系

    相信看到这篇文章的人,心中肯定有这样的想法:ODBC.OLEDB.ADO.ADO.NET貌似都是访问数据库的东东,那么他们之间有什么区别,又有什么联系呢?不要着急,待我慢慢道来. 先说ODBC,官方的 ...

  3. RefernceError : jQuery is not define

    使用ligerUI 的时候,代码没有什么错误,可是不能正常显示组件 ,火狐debug显演示样例如以下错误: 最后发现是引入文件的顺序错了,最好依照ligerui demo中的顺序引入js文件,这样就不 ...

  4. Android 如何添加一种锁屏方式

    前言          欢迎大家我分享和推荐好用的代码段~~ 声明          欢迎转载,但请保留文章原始出处:          CSDN:http://www.csdn.net        ...

  5. 《Java并发编程实战》第十一章 性能与可伸缩性 读书笔记

    造成开销的操作包含: 1. 线程之间的协调(比如:锁.触发信号以及内存同步等) 2. 添加�的上下文切换 3. 线程的创建和销毁 4. 线程的调度 一.对性能的思考 1 性能与可伸缩性 执行速度涉及下 ...

  6. send,recv,sendto,recvfrom

    send函数 int send( SOCKET s,    const char FAR *buf,    int len,    int flags ); 不论是客户还是server应用程序都用se ...

  7. 为什么for不能有序遍历数组的所有元素?(Array的设计原理)

    这个题目略微浅显,但却不易讲明白.如果我告诉你,我们不能以任何代码保证可以有序遍历出一个数组的所有元素,你肯定会反驳我,因为使用for明明就可以啊!但其实不是. 一.为什么FOR不能保证遍历所有? 代 ...

  8. IDispatch接口介绍

    1.         C程序调用时,调用者必须预先知道接口规范(如,参数类型.参数字节长度.参数顺序等).由于不同语言这些规范有所不同,COM未解决不同语言之间调用,提供了IDispatch接口. 2 ...

  9. 常用免费的WebServices地址

    天气预报Web服务,数据来源于中国气象局 公用事业http://www.webxml.com.cn/WebServices/WeatherWebService.asmx 中国股票行情分时走势预览缩略图 ...

  10. 手把手教你使用UICollectionView写公司的项目

    在很多app中都有这样通用的页面,一直没有机会使用UICollectionView,只是简单的看过他的使用方法.今天公司美工出图,使用了他,并且遇到了好多的坑.记录一下过程,不确定使用的方法是不是最优 ...