生产者/消费者模式

╰半橙微兮° 2022-06-10 13:23 282阅读 0赞

1.一生产与一消费:操作值
* 屁话没有,直接看例子
public class P {
private String lock;
public P(String lock){
super();
this.lock=lock;
}
public void setValue(){
try{
synchronized (lock){
if(!ValueObject.value.equals(“”)){
lock.wait();
}
String value=System.currentTimeMillis()+”_“+System.nanoTime();
System.out.println(“set 的值是”+value);
ValueObject.value=value;
lock.notify();
}
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
public class C {
private String lock;
public C(String lock){
super();
this.lock=lock;
}
public void getValue(){
try{
synchronized (lock){
if(ValueObject.value.equals(“”)){
lock.wait();
}
System.out.println(“get的值是”+ValueObject.value);
ValueObject.value=””;
lock.notify();
}
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
public class ValueObject {
public static String value=””;
}
public class ThreadP extends Thread{
private P p;
public ThreadP(P p){
super();
this.p=p;
}

  1. @Override
  2. public void run() \{
  3. while (true)\{
  4. p.setValue();
  5. \}
  6. \}
  7. \}
  8. public class ThreadC extends Thread\{
  9. private C r;
  10. public ThreadC(C r)\{
  11. super();
  12. this.r=r;
  13. \}
  14. @Override
  15. public void run() \{
  16. while(true)\{
  17. r.getValue();
  18. \}
  19. \}
  20. \}
  21. public class Run \{
  22. public static void main(String\[\] args)\{
  23. String lock=new String("");
  24. P p=new P(lock);
  25. C r=new C(lock);
  26. ThreadP threadP=new ThreadP(p);
  27. ThreadC threadC=new ThreadC(r);
  28. threadP.start();
  29. threadC.start();
  30. \}
  31. \}
  32. 交替执行,很完美
  1. 多生产与多消费:操作值-假死
    * 先看例子,找到问题
    1. public class C \{
    2. private String lock;
    3. public C(String lock)\{
    4. super();
    5. this.lock=lock;
    6. \}
    7. public void getValue()\{
    8. try\{
    9. synchronized (lock)\{
    10. while (ValueObject.value.equals(""))\{
    11. System.out.println("消费者 "+Thread.currentThread().getName()+" WAITING了\*");
    12. lock.wait();
    13. \}
    14. System.out.println("消费者 "+Thread.currentThread().getName()+" RUNNABLE了");
    15. ValueObject.value="";
    16. lock.notify();
    17. \}
    18. \}catch (InterruptedException e)\{
    19. e.printStackTrace();
    20. \}
    21. \}
    22. \}
    23. public class P \{
    24. private String lock;
  1. public P(String lock) \{
  2. super();
  3. this.lock = lock;
  4. \}
  5. public void setValue() \{
  6. try \{
  7. synchronized (lock) \{
  8. while (!ValueObject.value.equals("")) \{
  9. System.out.println("生产者" + Thread.currentThread().getName() + " WAITINGl \*");
  10. lock.wait();
  11. \}
  12. System.out.println("生产者 " + Thread.currentThread().getName() + " RUNNABLE了");
  13. String value = System.currentTimeMillis() + "\_" + System.nanoTime();
  14. ValueObject.value = value;
  15. lock.notify();
  16. \}
  17. \} catch (InterruptedException e) \{
  18. e.printStackTrace();
  19. \}
  20. \}
  21. \}
  22. public class ThreadC extends Thread \{
  23. private C c;
  24. public ThreadC(C r)\{
  25. super();
  26. this.c=r;
  27. \}
  28. @Override
  29. public void run() \{
  30. while(true)\{
  31. c.getValue();
  32. \}
  33. \}
  34. \}
  35. public class ThreadP extends Thread\{
  36. private P p;
  37. public ThreadP(P p)\{
  38. super();
  39. this.p=p;
  40. \}
  41. @Override
  42. public void run() \{
  43. while(true)\{
  44. p.setValue();
  45. \}
  46. \}
  47. \}
  48. public class Run \{
  49. public static void main(String\[\] args) throws InterruptedException\{
  50. String lock=new String("");
  51. P p=new P(lock);
  52. C r=new C(lock);
  53. ThreadP\[\] threadP=new ThreadP\[2\];
  54. ThreadC\[\] threadC=new ThreadC\[2\];
  55. for(int i=0;i<2;i++)\{
  56. threadP\[i\]=new ThreadP(p);
  57. threadP\[i\].setName("生产者 "+(i+1));
  58. threadC\[i\]=new ThreadC(r);
  59. threadC\[i\].setName("消费者 "+(i+1));
  60. threadP\[i\].start();
  61. threadC\[i\].start();
  62. \}
  63. Thread.sleep(5000);
  64. Thread\[\] threads=new Thread\[Thread.currentThread().getThreadGroup().activeCount()\];
  65. Thread.currentThread().getThreadGroup().enumerate(threads);
  66. for(int i=0;i<threads.length;i++)\{
  67. System.out.println(threads\[i\].getName()+" "+threads\[i\].getState());
  68. \}
  69. \}
  70. \}
  71. 效果:
  72. .....
  73. 消费者 消费者 2 WAITING\*
  74. 消费者 消费者 1 WAITING\*
  75. main RUNNABLE
  76. Monitor Ctrl-Break RUNNABLE
  77. 生产者 1 WAITING
  78. 消费者 1 WAITING
  79. 生产者 2 WAITING
  80. 消费者 2 WAITING
  81. \* 分析:notify()是随机唤醒的,他并不知道谁是生产者谁是消费者,仅仅去唤醒一个wait的线程
  82. 考虑这样一种情况:value中有数据,两个生产者都处于等待状态,然后执行了一个消费者线程,
  83. 线程中有数据了,唤醒一个线程,该线程为其中一个生产者,该生产者检测没有数据,生产一个数据,
  84. 然后唤醒一个线程,因为另外一个线程处于等待状态,所以刚好唤醒了该线程,如此,消费者就不能得到执行了,
  85. 就会陷入相互等待。
  86. \*解决办法:把notify()改成notifyAll()。

发表评论

表情:
评论列表 (有 0 条评论,282人围观)

还没有评论,来说两句吧...

相关阅读

    相关 关于生产者消费者模式

      什么是生产者消费者模式 在软件开发的过程中,经常碰到这样的场景: 某些模块负责生产数据,这些数据由其他模块来负责处理(此处的模块可能是:函数、线程、进程等)。产

    相关 生产者消费者设计模式

    生产者消费者设计模式 概述 > 有两个线程生产者和消费者,有一个任务队列(有大小限制,太大了阻塞当前的生产者,不让其生产)。队列中有put和take方法。 > > p