立即注册
 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
广州大学城网业务调整

[Java/JSP] 用线程解决生产者消费者问题 [复制链接] qrcode

查看: 3291 | 回复: 0

大法师的 该用户已被删除
发表于: 2013-1-7 16:06:42 | 显示全部楼层

  问题描述:
  生产者和消费者问题,我想大家肯定都很熟悉。就是有生产者在生产,生产出的产品(我们在这里用窝头来作比喻)放到一个篮子里,然后有消费者拿篮子里的窝头来吃。
  问题分析:
  1、条件分析,如果生产者生产了窝头,就应该叫消费者来吃;如果自己生产的窝头把篮子都装满了,就要先停下来,然后通知消费者去吃窝头;同理,消费者吃了窝头,应该叫生产者生产窝头,如果自己把篮子里的馒头都消费了,那么,就要先停下来,然后通知生产者生产窝头。
  2、我们用面向对象的分析方法来分析这个问题:
  其中的对象有:生产者(Producer)、消费者(Consumer)、篮子(SyncStack)、窝头(WoTou)
  我写的代码如下:
  [java]
  复制 打印
  1. public class ProducerConsumer
  2. {
  3. public static void main(String[] args)
  4. {
  5. SyncStack ss=new SyncStack();
  6. new Thread(new Producer(ss)).start();
  7. new Thread(new Consumer(ss)).start();
  8. }
  9. }
  10.
  11. class WoTou
  12. {
  13. int id;
  14. WoTou(int id)
  15. {
  16. this.id=id;
  17. }
  18.
  19. public String toString()
  20. {
  21. return "窝头"+id;
  22. }
  23. }
  24.
  25. //生产池
  26. class SyncStack
  27. {
  28. int index=0; //标记现在有几个馒头
  29. WoTou[] arrayWoTou=new WoTou[6];
  30.
  31. //生产者向生产池中放入窝头
  32. public synchronized void push(WoTou wt)
  33. {
  34. //要用while不用能if 如果用if的话出现例外后,会继续向下执行,索引溢出
  35. while(index>=6)
  36. {
  37. try
  38. {
  39. this.wait();
  40. }
  41. catch(InterruptedException e)
  42. {
  43. e.printStackTrace();
  44. }
  45. }
  46.
  47. notify();
  48. arrayWoTou[index]=wt;
  49. index++;
  50. }
  51.
  52. //消费者从生活池中消费窝头
  53. public synchronized WoTou pop()
  54. {
  55. while(index<=0)
  56. {
  57. try
  58. {
  59. this.wait();
  60. }
  61. catch(InterruptedException e)
  62. {
  63. e.printStackTrace();
  64. }
  65. }
  66.
  67. notify();
  68. //先要index--因为index记录的是当前窝头的个数
  69. index--;
  70. return arrayWoTou[index];
  71. }
  72. }
  73.
  74. //生产者
  75. class Producer implements Runnable
  76. {
  77. SyncStack ss=new SyncStack();
  78. Producer(SyncStack ss)
  79. {
  80. this.ss=ss;
  81. }
  82. public void run()
  83. {
  84. for(int i=1;i<=10;i++)
  85. {
  86. WoTou wt=new WoTou(i);
  87. ss.push(wt);
  88. System.out.println("生产了:"+wt);
  89. }
  90. }
  91. }
  92.
  93. //消费者
  94. class Consumer implements Runnable
  95. {
  96. SyncStack ss=new SyncStack();
  97. Consumer(SyncStack ss)
  98. {
  99. this.ss=ss;
  100. }
  101. public void run()
  102. {
  103. for(int i=1;i<=10;i++)
  104. {
  105. WoTou wt=null;
  106. wt=ss.pop();
  107. System.out.println("消费了"+wt);
  108. }
  109. }
  110. }
  public class ProducerConsumer
  {
  public static void main(String[] args)
  {
  SyncStack ss=new SyncStack();
  new Thread(new Producer(ss)).start();
  new Thread(new Consumer(ss)).start();
  }
  }
  class WoTou
  {
  int id;
  WoTou(int id)
  {
  this.id=id;
  }
  public String toString()
  {
  return "窝头"+id;
  }
  }
  //生产池
  class SyncStack
  {
  int index=0; //标记现在有几个馒头
  WoTou[] arrayWoTou=new WoTou[6];
  //生产者向生产池中放入窝头
  public synchronized void push(WoTou wt)
  {
  //要用while不用能if 如果用if的话出现例外后,会继续向下执行,索引溢出
  while(index>=6)
  {
  try
  {
  this.wait();
  }
  catch(InterruptedException e)
  {
  e.printStackTrace();
  }
  }
  notify();
  arrayWoTou[index]=wt;
  index++;
  }
  //消费者从生活池中消费窝头
  public synchronized WoTou pop()
  {
  while(index<=0)
  {
  try
  {
  this.wait();
  }
  catch(InterruptedException e)
  {
  e.printStackTrace();
  }
  }
  notify();
  //先要index--因为index记录的是当前窝头的个数
  index--;
  return arrayWoTou[index];
  }
  }
  //生产者
  class Producer implements Runnable
  {
  SyncStack ss=new SyncStack();
  Producer(SyncStack ss)
  {
  this.ss=ss;
  }
  public void run()
  {
  for(int i=1;i<=10;i++)
  {
  WoTou wt=new WoTou(i);
  ss.push(wt);
  System.out.println("生产了:"+wt);
  }
  }
  }
  //消费者
  class Consumer implements Runnable
  {
  SyncStack ss=new SyncStack();
  Consumer(SyncStack ss)
  {
  this.ss=ss;
  }
  public void run()
  {
  for(int i=1;i<=10;i++)
  {
  WoTou wt=null;
  wt=ss.pop();
  System.out.println("消费了"+wt);
  }
  }
  }
  1、一个时间点只有一个进程在这个对象上
  2、如果是多个生产者或者消费者的话,生产和消费的数量应该一致,比如说如果再增加两个生产者,每个生产者都还是生产20个,可是只有一个消费者,总共消费20个,会出现满的情况;还有就是调用notifyAll(),在这个对象上的线程一哄而起,谁抢到算谁的。
  QQ 744437114
  疯狂软件官网:http://www.fkjava.org
  疯狂java视频 android视频:http://www.fkjava.org/video.html
跳转到指定楼层
快速回复 返回顶部 返回列表