【郭林专刊】多线程知识总结线程通信,wait()与notify()的运用

编写一个生产与消费的程序,具体要求:店主告诉生产者生产一组产品,生产者生产出之后运给店主,店主通知生产者我们这里只放得下一组产品你等等再生产,店主通知消费者取走这组产品,店主通知消费者你等等,我们这里没有产品了,店主告诉生产者生产一组产品,生产者生产出之后运给店主,店主通知生产者... ...就是这样一个运作流程(如下图所示).

【郭林专刊】多线程知识总结线程通信,wait()与notify()的运用

代码:

  1. classShengChanimplementsRunnable
  2. {
  3. DianZhud;
  4. publicShengChan(DianZhud)
  5. {
  6. this.d=d;
  7. }
  8. publicvoidrun()
  9. {
  10. inti=0;
  11. while(true)
  12. {
  13. System.out.println("");//很奇怪,去掉这行就不能交替运行了,知道的网友,请赐教,谢谢.
  14. if(i==0)
  15. {
  16. d.put("001","洗衣机");
  17. }
  18. else
  19. {
  20. d.put("002","冰箱");
  21. }
  22. i=(i+1)%2;
  23. }
  24. }
  25. }
  26. classXiaoFeiimplementsRunnable
  27. {
  28. DianZhud;
  29. publicXiaoFei(DianZhud)
  30. {
  31. this.d=d;
  32. }
  33. publicvoidrun()
  34. {
  35. while(true)
  36. {
  37. d.get();
  38. }
  39. }
  40. }
  41. classDianZhu
  42. {
  43. privateStringproID="";
  44. privateStringproName="";
  45. privatebooleanisFull=false;//店主放的产品是否满了?默认为false;表示未满.
  46. publicsynchronizedvoidput(StringproID,StringproName)
  47. {
  48. if(isFull==false)//如果是空的.
  49. {
  50. //生产产品
  51. this.proID=proID;
  52. this.proName=proName;
  53. isFull=true;//产品已经生产好
  54. //System.out.println(Thread.currentThread().getName()+":生产完毕!");
  55. notify();//通知[消费线程]工作,注意:notify();具备有先启动,等该线程休息,才生效的特性
  56. }
  57. else//如果是满的,[生产线程]休息
  58. {
  59. //System.out.println(Thread.currentThread().getName()+":休息!\n");
  60. try{wait();}catch(Exceptione){e.printStackTrace();}
  61. }
  62. }
  63. publicsynchronizedvoidget()
  64. {
  65. if(isFull==true)//如果有产品
  66. {
  67. //消费者取走产品
  68. System.out.println("proID:"+proID);
  69. System.out.println("proName:"+proName);
  70. isFull=false;//消费者已经取走产品
  71. //System.out.println(Thread.currentThread().getName()+":取产品完毕!");
  72. notify();//通知[生产线程]工作
  73. }
  74. else//如果没有产品,[消费线程]休息
  75. {
  76. //System.out.println(Thread.currentThread().getName()+":休息!\n");
  77. try{wait();}catch(Exceptione){e.printStackTrace();}
  78. }
  79. }
  80. }
  81. publicclassShengChanLian
  82. {
  83. publicstaticvoidmain(String[]args)
  84. {
  85. DianZhud=newDianZhu();
  86. ShengChans=newShengChan(d);//创建对象的同时把DianZhu对象传过去
  87. XiaoFeix=newXiaoFei(d);
  88. //启动线程
  89. newThread(s).start();
  90. newThread(x).start();
  91. }
  92. }
class ShengChan implements Runnable { DianZhu d; public ShengChan(DianZhu d) { this.d=d; } public void run() { int i=0; while(true) { System.out.println("");//很奇怪,去掉这行就不能交替运行了,知道的网友,请赐教,谢谢. if(i==0) { d.put("001","洗衣机"); } else { d.put("002","冰箱"); } i=(i+1)%2; } } } class XiaoFei implements Runnable { DianZhu d; public XiaoFei(DianZhu d) { this.d=d; } public void run() { while(true) { d.get(); } } } class DianZhu { private String proID=""; private String proName=""; private boolean isFull=false;//店主放的产品是否满了?默认为false;表示未满. public synchronized void put(String proID,String proName) { if(isFull==false)//如果是空的. { //生产产品 this.proID=proID; this.proName=proName; isFull=true;//产品已经生产好 // System.out.println(Thread.currentThread().getName()+":生产完毕!"); notify();//通知[消费线程]工作,注意:notify();具备有先启动,等该线程休息,才生效的特性 } else//如果是满的,[生产线程]休息 { // System.out.println(Thread.currentThread().getName()+":休息!\n"); try{wait();}catch(Exception e){e.printStackTrace();} } } public synchronized void get() { if(isFull==true)//如果有产品 { //消费者取走产品 System.out.println("proID:"+proID); System.out.println("proName:"+proName); isFull=false;//消费者已经取走产品 // System.out.println(Thread.currentThread().getName()+":取产品完毕!"); notify();//通知[生产线程]工作 } else//如果没有产品,[消费线程]休息 { // System.out.println(Thread.currentThread().getName()+":休息!\n"); try{wait();}catch(Exception e){e.printStackTrace();} } } } public class ShengChanLian { public static void main(String[]args) { DianZhu d=new DianZhu(); ShengChan s=new ShengChan(d);//创建对象的同时把DianZhu对象传过去 XiaoFei x=new XiaoFei(d); //启动线程 new Thread(s).start(); new Thread(x).start(); } }

输出结果:

【郭林专刊】多线程知识总结线程通信,wait()与notify()的运用

<style type="text/css"> <!-- .gh_bg {font-size:12px; width:100%; background-color:#E7E5DC} .****_des {background-color:#E7E5DC; height:26px; line-height:26px; overflow:hidden; float:left; padding:4px} .****_call {background-color:#000; color:#FFF; height:26px; line-height:26px; float:left; border-right:solid 3 #F00; padding:4px} .string {color:#F00; font-weight:bold} .gh_clear {clear:both; overflow:hidden; width:0px; height:0px} --> </style>