生产者消费者模式
来源:互联网 发布:淘宝买电脑可靠吗 编辑:程序博客网 时间:2024/05/21 07:10
生产者、消费者模式
1、一生产与一消费,操作值
package me.mymilkbottles.Study04;import java.util.Date;/** * Created by Administrator on 2017/07/16 8:29. */public class OnePOneCValue { public static void main(String[] args) { P1 p1 = new P1("hello"); C1 c1 = new C1("hello"); MyThreadC1 myThreadC1 = new MyThreadC1(c1); myThreadC1.start(); MyThreadP1 myThreadP1 = new MyThreadP1(p1); myThreadP1.start();// for (int i = 0; i < 10; ++i) {// MyThreadC1 myThreadC1 = new MyThreadC1(c1);// myThreadC1.start();// MyThreadP1 myThreadP1 = new MyThreadP1(p1);// myThreadP1.start();// } }}class ValueObject { public static String value = null;}class P1 { private String lock; public P1(String lock) { this.lock = lock; } public void set() throws InterruptedException { synchronized (lock) { if (ValueObject.value != null) { lock.wait(); } ValueObject.value = String.valueOf(System.nanoTime()); System.out.println("set " + ValueObject.value); lock.notify(); } }}class C1 { private String lock; public C1(String lock) { this.lock = lock; } public void get() throws InterruptedException { synchronized (lock) { if (ValueObject.value == null) { lock.wait(); } System.out.println("get " + ValueObject.value); ValueObject.value = null; lock.notify(); } }}class MyThreadP1 extends Thread { private P1 p1; public MyThreadP1(P1 p1) { this.p1 = p1; } @Override public void run() { while (true) { try { p1.set(); } catch (InterruptedException e) { e.printStackTrace(); } } }}class MyThreadC1 extends Thread { private C1 c1; public MyThreadC1(C1 c1) { this.c1 = c1; } @Override public void run() { while (true) { try { c1.get(); } catch (InterruptedException e) { e.printStackTrace(); } } }}
如果在此基础上,设计出多个生产者和多个消费者,那么在运行的过程中极有可能出现假死的情况,也就是所有的线程都呈WAITING等待状态。
2、多生产与多消费:操作值-假死
package me.mymilkbottles.Study04;import java.util.Date;/** * Created by Administrator on 2017/07/16 8:29. */public class OnePOneCValue { public static void main(String[] args) { P1 p1 = new P1("hello"); C1 c1 = new C1("hello");// MyThreadC1 myThreadC1 = new MyThreadC1(c1);// myThreadC1.start();// MyThreadP1 myThreadP1 = new MyThreadP1(p1);// myThreadP1.start(); for (int i = 0; i < 10; ++i) { MyThreadC1 myThreadC1 = new MyThreadC1(c1); myThreadC1.setName("消费者" + i); myThreadC1.start(); MyThreadP1 myThreadP1 = new MyThreadP1(p1); myThreadP1.setName("生产者" + i); myThreadP1.start(); } }}class ValueObject { public static String value = null;}class P1 { private String lock; public P1(String lock) { this.lock = lock; } public void set() throws InterruptedException { synchronized (lock) { while (ValueObject.value != null) { lock.wait(); } ValueObject.value = String.valueOf(System.nanoTime()); System.out.println("set " + ValueObject.value); lock.notify(); } }}class C1 { private String lock; public C1(String lock) { this.lock = lock; } public void get() throws InterruptedException { synchronized (lock) { while (ValueObject.value == null) { lock.wait(); } System.out.println("get " + ValueObject.value); ValueObject.value = null; lock.notify(); } }}class MyThreadP1 extends Thread { private P1 p1; public MyThreadP1(P1 p1) { this.p1 = p1; } @Override public void run() { while (true) { try { p1.set(); } catch (InterruptedException e) { e.printStackTrace(); } } }}class MyThreadC1 extends Thread { private C1 c1; public MyThreadC1(C1 c1) { this.c1 = c1; } @Override public void run() { while (true) { try { c1.get(); } catch (InterruptedException e) { e.printStackTrace(); } } }}
我们可以打印当前线程的状态信息:
try { Thread.sleep(6000);} catch (InterruptedException e) { e.printStackTrace();}Thread[] threads = new Thread[Thread.activeCount()];Thread.currentThread().getThreadGroup().enumerate(threads);for (Thread thread : threads) { System.out.println(thread.getName() + " " + thread.getState());}
打印结果如下:
main RUNNABLEMonitor Ctrl-Break RUNNABLE消费者0 WAITING生产者0 WAITING消费者1 WAITING生产者1 WAITING消费者2 WAITING生产者2 WAITING消费者3 WAITING生产者3 WAITING消费者4 WAITING生产者4 WAITING消费者5 WAITING生产者5 WAITING消费者6 WAITING生产者6 WAITING消费者7 WAITING生产者7 WAITING消费者8 WAITING生产者8 WAITING消费者9 WAITING生产者9 WAITING
可以看到,所有的线程都在WAITING状态,这是因为虽然我们使用了notify通知,但是不能保证notify唤醒的就一定是异类,如果唤醒的是同类,比如:生产者唤醒了生产者,那么这样的情况累积下来,就会导致所有的线程都在等待,程序最后也成了假死状态。
3、多生产与多消费:操作值
为了避免假死的情况,解决的办法就是将notify改成notifyAll即可。
package me.mymilkbottles.Study04;import java.util.Date;/** * Created by Administrator on 2017/07/16 8:29. */public class OnePOneCValue { public static void main(String[] args) { P1 p1 = new P1("hello"); C1 c1 = new C1("hello");// MyThreadC1 myThreadC1 = new MyThreadC1(c1);// myThreadC1.start();// MyThreadP1 myThreadP1 = new MyThreadP1(p1);// myThreadP1.start(); for (int i = 0; i < 10; ++i) { MyThreadC1 myThreadC1 = new MyThreadC1(c1); myThreadC1.setName("消费者" + i); myThreadC1.start(); MyThreadP1 myThreadP1 = new MyThreadP1(p1); myThreadP1.setName("生产者" + i); myThreadP1.start(); } try { Thread.sleep(6000); } catch (InterruptedException e) { e.printStackTrace(); } Thread[] threads = new Thread[Thread.activeCount()]; Thread.currentThread().getThreadGroup().enumerate(threads); for (Thread thread : threads) { System.out.println(thread.getName() + " " + thread.getState()); } }}class ValueObject { public static String value = null;}class P1 { private String lock; public P1(String lock) { this.lock = lock; } public void set() throws InterruptedException { synchronized (lock) { while (ValueObject.value != null) { lock.wait(); } ValueObject.value = String.valueOf(System.nanoTime()); System.out.println("set " + ValueObject.value); lock.notifyAll(); } }}class C1 { private String lock; public C1(String lock) { this.lock = lock; } public void get() throws InterruptedException { synchronized (lock) { while (ValueObject.value == null) { lock.wait(); } System.out.println("get " + ValueObject.value); ValueObject.value = null; lock.notifyAll(); } }}class MyThreadP1 extends Thread { private P1 p1; public MyThreadP1(P1 p1) { this.p1 = p1; } @Override public void run() { while (true) { try { p1.set(); } catch (InterruptedException e) { e.printStackTrace(); } } }}class MyThreadC1 extends Thread { private C1 c1; public MyThreadC1(C1 c1) { this.c1 = c1; } @Override public void run() { while (true) { try { c1.get(); } catch (InterruptedException e) { e.printStackTrace(); } } }}
4、一生产与一消费:操作栈
package me.mymilkbottles.Study04;import java.util.ArrayList;import java.util.List;/** * Created by Administrator on 2017/07/16 9:27. */public class OnePOneCStack { public static void main(String[] args) { P2 p2 = new P2("hello"); C2 c2 = new C2("hello"); MyThreadC2 myThreadC2 = new MyThreadC2(c2); myThreadC2.start(); MyThreadP2 myThreadP2 = new MyThreadP2(p2); myThreadP2.start(); }}class ListObject { public static List<String> list = new ArrayList<>();}class P2 { private String lock; public P2(String lock) { this.lock = lock; } public void set() throws InterruptedException { synchronized (lock) { if (ListObject.list.size() == 1) { lock.wait(); } String value = String.valueOf(System.nanoTime()); ListObject.list.add(value); System.out.println("set " + value); lock.notify(); } }}class C2 { private String lock; public C2(String lock) { this.lock = lock; } public void get() throws InterruptedException { synchronized (lock) { if (ListObject.list.size() == 0) { lock.wait(); } System.out.println("get " + ListObject.list.get(0)); ListObject.list.remove(0); lock.notify(); } }}class MyThreadP2 extends Thread { private P2 p2; public MyThreadP2(P2 p2) { this.p2 = p2; } @Override public void run() { while (true) { try { p2.set(); } catch (InterruptedException e) { e.printStackTrace(); } } }}class MyThreadC2 extends Thread { private C2 c2; public MyThreadC2(C2 c2) { this.c2 = c2; } @Override public void run() { while (true) { try { c2.get(); } catch (InterruptedException e) { e.printStackTrace(); } } }}
5、一生产与多消费-操作栈:解决wait条件改变与假死
package me.mymilkbottles.Study04;import java.util.ArrayList;import java.util.List;/** * Created by Administrator on 2017/07/16 9:27. */public class OnePOneCStack { public static void main(String[] args) { P2 p2 = new P2("hello"); C2 c2 = new C2("hello"); MyThreadP2 myThreadP2 = new MyThreadP2(p2); myThreadP2.start(); for (int i = 0; i < 10; ++i) { MyThreadC2 myThreadC2 = new MyThreadC2(c2); myThreadC2.start(); } }}class ListObject { public static List<String> list = new ArrayList<>();}class P2 { private String lock; public P2(String lock) { this.lock = lock; } public void set() throws InterruptedException { synchronized (lock) { if (ListObject.list.size() == 1) { lock.wait(); } String value = String.valueOf(System.nanoTime()); ListObject.list.add(value); System.out.println("set " + value); lock.notify(); } }}class C2 { private String lock; public C2(String lock) { this.lock = lock; } public void get() throws InterruptedException { synchronized (lock) { if (ListObject.list.size() == 0) { lock.wait(); } System.out.println("get " + ListObject.list.get(0)); ListObject.list.remove(0); lock.notify(); } }}class MyThreadP2 extends Thread { private P2 p2; public MyThreadP2(P2 p2) { this.p2 = p2; } @Override public void run() { while (true) { try { p2.set(); } catch (InterruptedException e) { e.printStackTrace(); } } }}class MyThreadC2 extends Thread { private C2 c2; public MyThreadC2(C2 c2) { this.c2 = c2; } @Override public void run() { while (true) { try { c2.get(); } catch (InterruptedException e) { e.printStackTrace(); } } }}/*执行结果:Exception in thread "Thread-7" java.lang.IndexOutOfBoundsException: Index: 0, Size: 0 at java.util.ArrayList.rangeCheck(ArrayList.java:635) at java.util.ArrayList.get(ArrayList.java:411) at me.mymilkbottles.Study04.C2.get(OnePOneCStack.java:56) at me.mymilkbottles.Study04.MyThreadC2.run(OnePOneCStack.java:89)set 5055921991938get 5055921991938*/
可以看到结果出现了IndexOutOfBoundsException,原因是因为条件发生改变的时候并没有得到及时的响应,所以多个呈wait状态的线程被唤醒,继而执行remove的时候越界。
解决的方法就是将if改为while。
package me.mymilkbottles.Study04;import java.util.ArrayList;import java.util.List;/** * Created by Administrator on 2017/07/16 9:27. */public class OnePOneCStack { public static void main(String[] args) { P2 p2 = new P2("hello"); C2 c2 = new C2("hello"); MyThreadP2 myThreadP2 = new MyThreadP2(p2); myThreadP2.setName("生产者1"); myThreadP2.start(); for (int i = 0; i < 10; ++i) { MyThreadC2 myThreadC2 = new MyThreadC2(c2); myThreadC2.setName("消费者" + i); myThreadC2.start(); } try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } Thread[] threads = new Thread[Thread.activeCount()]; Thread.currentThread().getThreadGroup().enumerate(threads); for (Thread thread : threads) { System.out.println(thread.getName() + " : " + thread.getState()); } }}class ListObject { public static List<String> list = new ArrayList<>();}class P2 { private String lock; public P2(String lock) { this.lock = lock; } public void set() throws InterruptedException { synchronized (lock) { while (ListObject.list.size() == 1) { lock.wait(); } String value = String.valueOf(System.nanoTime()); ListObject.list.add(value); System.out.println("set " + value); lock.notify(); } }}class C2 { private String lock; public C2(String lock) { this.lock = lock; } public void get() throws InterruptedException { synchronized (lock) { while (ListObject.list.size() == 0) { lock.wait(); } System.out.println("get " + ListObject.list.get(0)); ListObject.list.remove(0); lock.notify(); } }}class MyThreadP2 extends Thread { private P2 p2; public MyThreadP2(P2 p2) { this.p2 = p2; } @Override public void run() { while (true) { try { p2.set(); } catch (InterruptedException e) { e.printStackTrace(); } } }}class MyThreadC2 extends Thread { private C2 c2; public MyThreadC2(C2 c2) { this.c2 = c2; } @Override public void run() { while (true) { try { c2.get(); } catch (InterruptedException e) { e.printStackTrace(); } } }}/*执行结果:set 5437922928284get 5437922928284set 5437923471854get 5437923471854main : RUNNABLEMonitor Ctrl-Break : RUNNABLE生产者1 : WAITING消费者0 : WAITING消费者1 : WAITING消费者2 : WAITING消费者3 : WAITING消费者4 : WAITING消费者5 : WAITING消费者6 : WAITING消费者7 : WAITING消费者8 : WAITING消费者9 : WAITING*/
可以看到又和上面的情况(唤醒同类)类似了,那么我们使用notifyAll即可解决。
6、多生产与一消费:操作栈
这种情况和一生产和多消费是类似的。
7、多生产与多消费:操作栈
这种情况和上面两种的情况也是类似的。
阅读全文
0 0
- 生产者—消费者模式
- 生产者-消费者模式
- 消费者与生产者模式
- 消费者与生产者模式
- 消费者与生产者模式
- 生产者消费者模式浅析
- 生产者消费者模式
- 生产者/消费者模式
- 生产者/消费者模式
- 生产者-消费者模式
- 【转】生产者消费者模式
- 生产者、消费者模式
- 生产者/消费者模式
- 生产者/消费者模式
- 生产者/消费者模式(转载)
- 生产者消费者模式浅析
- 生产者消费者模式浅析
- 生产者消费者模式
- Python matplotlib
- 谁获得了最高奖学金
- SpringBoot整合WebSocket案例
- python爬虫爬取网页表格数据
- 全文检索技术 solr(三)solr安装、启动
- 生产者消费者模式
- (65)LinkLIst练习:运用LinkList方法模拟堆栈、队列
- RB_TREE 红黑树插入及删除
- angular2-使用bootstrap-select插件
- HDU 2844&& POJ 1742
- 【剑指offer】面试题 30:包含 min 函数的栈
- 线程间通信
- 华为机试:二维数组操作、公共字串计算
- 考研英语笔记——时文长难句一