Java 实例 - 生产者/消费者问题

生产者和消费者问题是线程模型中的经典问题:生产者和消费者在同一时间段内共用同一个存储空间,如下图所示,生产者向空间里存放数据,而消费者取用数据,如果不加以协调可能会出现以下情况:

存储空间已满,而生产者占用着它,消费者等着生产者让出空间从而去除产品,生产者等着消费者消费产品,从而向空间中添加产品。互相等待,从而发生死锁。

Java 实例 - 生产者/消费者问题

以下实例演示了如何通过线程解决生产者/消费者问题:

  1. /*
  2. author by java
  3. ProducerConsumerTest.java
  4. */
  5. public class ProducerConsumerTest {
  6. public static void main(String[] args) {
  7. CubbyHole c = new CubbyHole();
  8. Producer p1 = new Producer(c, 1);
  9. Consumer c1 = new Consumer(c, 1);
  10. p1.start();
  11. c1.start();
  12. }
  13. }
  14. class CubbyHole {
  15. private int contents;
  16. private boolean available = false;
  17. public synchronized int get() {
  18. while (available == false) {
  19. try {
  20. wait();
  21. }
  22. catch (InterruptedException e) {
  23. }
  24. }
  25. available = false;
  26. notifyAll();
  27. return contents;
  28. }
  29. public synchronized void put(int value) {
  30. while (available == true) {
  31. try {
  32. wait();
  33. }
  34. catch (InterruptedException e) {
  35. }
  36. }
  37. contents = value;
  38. available = true;
  39. notifyAll();
  40. }
  41. }
  42. class Consumer extends Thread {
  43. private CubbyHole cubbyhole;
  44. private int number;
  45. public Consumer(CubbyHole c, int number) {
  46. cubbyhole = c;
  47. this.number = number;
  48. }
  49. public void run() {
  50. int value = 0;
  51. for (int i = 0; i < 10; i++) {
  52. value = cubbyhole.get();
  53. System.out.println("消费者 #" + this.number+ " got: " + value);
  54. }
  55. }
  56. }
  57. class Producer extends Thread {
  58. private CubbyHole cubbyhole;
  59. private int number;
  60. public Producer(CubbyHole c, int number) {
  61. cubbyhole = c;
  62. this.number = number;
  63. }
  64. public void run() {
  65. for (int i = 0; i < 10; i++) {
  66. cubbyhole.put(i);
  67. System.out.println("生产者 #" + this.number + " put: " + i);
  68. try {
  69. sleep((int)(Math.random() * 100));
  70. } catch (InterruptedException e) { }
  71. }
  72. }
  73. }

以上代码运行输出结果为:

  1. 消费者 #1 got: 0
  2. 生产者 #1 put: 0
  3. 生产者 #1 put: 1
  4. 消费者 #1 got: 1
  5. 生产者 #1 put: 2
  6. 消费者 #1 got: 2
  7. 生产者 #1 put: 3
  8. 消费者 #1 got: 3
  9. 生产者 #1 put: 4
  10. 消费者 #1 got: 4
  11. 生产者 #1 put: 5
  12. 消费者 #1 got: 5
  13. 生产者 #1 put: 6
  14. 消费者 #1 got: 6
  15. 生产者 #1 put: 7
  16. 消费者 #1 got: 7
  17. 生产者 #1 put: 8
  18. 消费者 #1 got: 8
  19. 生产者 #1 put: 9
  20. 消费者 #1 got: 9