歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> Java多線程總結六:經典生產者消費者問題實現

Java多線程總結六:經典生產者消費者問題實現

日期:2017/3/1 10:55:58   编辑:Linux編程

這是個線程同步的經典例子,源代碼如下:

  1. 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. }

運行結果:

生產者 生產了產品(產品ID:090505105 產品名稱:電話)
消費者 消費了產品(產品ID:090505105 產品名稱:電話)

Copyright © Linux教程網 All Rights Reserved