java多线程总结六:经典生产者消费者问题实现

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

[java] view plaincopy

  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 产品名称:电话)

时间: 2024-10-11 16:42:42

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

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

前言:最近在学习Java多线程,看到ImportNew网上有网友翻译的一篇文章<阻塞队列实现生产者消费者模式>.在文中,使用的是Java的concurrent包中的阻塞队列来实现.在看完后,自行实现阻塞队列. (一)准备 在多线程中,生产者-消费者问题是一个经典的多线程同步问题.简单来说就是有两种线程(在这里也可以做进程理解)——生产者和消费者,他们共享一个固定大小的缓存区(如一个队列).生产者负责产生放入新数据,消费者负责取出缓存区的数据.具体介绍请参考 Producer-consumer

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

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

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

两个线程一个生产者个一个消费者 需求情景 两个线程,一个负责生产,一个负责消费,生产者生产一个,消费者消费一个 涉及问题 同步问题:如何保证同一资源被多个线程并发访问时的完整性.常用的同步方法是采用标记或加锁机制 wait() / nofity() 方法是基类Object的两个方法,也就意味着所有Java类都会拥有这两个方法,这样,我们就可以为任何对象实现同步机制. wait()方法:当缓冲区已满/空时,生产者/消费者线程停止自己的执行,放弃锁,使自己处于等等状态,让其他线程执行. notify

java中多线程通信实例:生产者消费者模式

线程间的通信: 其实就是多个线程再操作同一个资源,但是操作的动作不同   当某个线程进入synchronized块后,共享数据的状态不一定满足该线程的需要,需要其他线程改变共享数据的状态后才能运行,而由于当时线程对共享资源时独占的,它必须解除对共享资源的锁定的状态,通知其他线程可以使用该共享资源. Java中的 wait(),notify(),notifyAll()可以实现线程间的通信. 生产者--消费者问题是典型的线程同步和通信问题 /** * 生产者和消费者问题,生产者生成出产品,消费者去购

11.9-全栈Java笔记: 线程并发协作(生产者/消费者模式)

多线程环境下,我们经常需要多个线程的并发和协作.这个时候,就需要了解一个重要的多线程并发协作模型"生产者消费者模式". 什么是生产者? 生产者指的是负责生产数据的模块(这里模块可能是:方法.对象.线程.进程). 什么是消费者? 消费者指的是负责处理数据的模块(这里模块可能是:方法.对象.线程.进程). 什么是缓冲区? 消费者不能直接使用生产者的数据,它们之间有个"缓冲区".生产者将生产好的数据放入"缓冲区",消费者从"缓冲区"

JS实现经典生产者消费者模型

由于node使用单线程的方式实现,所以,在此使用定时器timer代替线程thread来实现生产者消费者模型. 代码如下: var sigintCount = 0; var productArray = []; var productArrayLen = 0; var productLock = false; var PRODUCT_ARRAY_THRESHOLD = 10; var producerTimer = setInterval(function () { if (!productLoc

Java 多线程(六) synchronized关键字详解

Java 多线程(六) synchronized关键字详解 多线程的同步机制对资源进行加锁,使得在同一个时间,只有一个线程可以进行操作,同步用以解决多个线程同时访问时可能出现的问题. 同步机制可以使用synchronized关键字实现. 当synchronized关键字修饰一个方法的时候,该方法叫做同步方法. 当synchronized方法执行完或发生异常时,会自动释放锁. 下面通过一个例子来对synchronized关键字的用法进行解析. 1.是否使用synchronized关键字的不同 例子

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

对于多线程程序来说,不管任何编程语言,生产者消费者模型都是最经典的. 实际上,准确的说应该是"生产者-消费者-仓储"模型,离开了仓储,生产者消费者模型就显得没有说服力了. 对于此模型,应该明确以下几点: 生产者仅仅在仓储未满时候生产,仓满则停止生产. 消费者仅仅在仓储有产品时候才能消费,仓空则等待. 当消费者发现仓储没有产品的时候会通知生产者生产. 生产者在生产出可消费产品时候,应该通知消费者去消费. 此模型将要结合java.lang.Object的wait与notify,notify

转----秒杀多线程第十篇 生产者消费者问题

继经典线程同步问题之 后,我们来看看生产者消费者问题及读者写者问题.生产者消费者问题是一个著名的线程同步问题,该问题描述如下:有一个生产者在生产产品,这些产品将提供给 若干个消费者去消费,为了使生产者和消费者能并发执行,在两者之间设置一个具有多个缓冲区的缓冲池,生产者将它生产的产品放入一个缓冲区中,消费者可以从 缓冲区中取走产品进行消费,显然生产者和消费者之间必须保持同步,即不允许消费者到一个空的缓冲区中取产品,也不允许生产者向一个已经放入产品的缓冲区中 再次投放产品. 这个生产者消费者题目不仅