生产者与消费者一对一,一对多,多对多
来源:互联网 发布:分布式java应用 编辑:程序博客网 时间:2024/06/05 16:30
生产者与消费者问题涉及对象
- 生产者
- 消费者
- 生产与消费对象 (以下简称目标对象,通常是通过某个容器存放如:ArrayList)
类图表示:
生产者与消费者问题主要解决的是同步问题:
- 当目标对象已经为0,或已经不存在时,这时消费者就不能再继续消费了,所以要让生产者先生产目标对象。
- 当目标对象达到一定数量时应停止生产了,这时生产者应停止继续生产,需要消费者先进行消费目标对象。
可知三者关系,生产者与消费者共同作用于目标对象,但生产者与消费者之间又存在先后关系。
生产者——>生成一定量的数据放到缓冲区中,然后重复此过程;
消费者——>在缓冲区消耗这些数据。
而生产者-消费者之间存在三种关系,即
生产者与生产者之间是互斥关系;
消费者与消费者之间是互斥关系;
生产者与消费者之间是同步与互斥关系。
下面直接用代码讲解:
消费者与生产者一对一:
//目标对象类
package 生产者与消费者一对一队列操作;import java.util.ArrayList;import java.util.List;public class CookieList { public static final int MAX_SIZE = 1; private List<String> list = new ArrayList<String>(); public synchronized void product(){ try{ if(list.size()==MAX_SIZE) this.wait(); list.add("cookie"+((int)(Math.random()*10)+1)); System.out.println("生产者生产了"+list.get(0)); this.notify(); }catch(InterruptedException e){ } } public synchronized void customer(){ try{ if(list.size()==0) this.wait(); System.out.println("消费者消费了:"+list.get(0)); list.remove(0); this.notify(); }catch(InterruptedException e){ } }}
Main类
package 生产者与消费者一对一队列操作;public class Main { public static void main(String[] args) { CookieList cookieList = new CookieList(); P p = new P(cookieList); C c = new C(cookieList); p.start(); c.start(); } //生产者线程 public static class P extends Thread{ public CookieList cookieList; public P(CookieList cookieList){ this.cookieList = cookieList; } @Override public void run() { while(true){ this.cookieList.product(); try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); } } } } //消费者线程 public static class C extends Thread{ public CookieList cookieList; public C(CookieList cookieList){ this.cookieList = cookieList; } @Override public void run() { while(true){ this.cookieList.customer(); try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); } } } }}
对于多消费或多生产需要注意的点
比如针对消费者,当需要唤醒生产者生产时可以调用notify()方法,但notify()方法并不能指定唤醒监视队列特定的线程而是随机唤醒的,当多个消费者的时候一个消费者唤醒的可能是另一个消费者线程而不是生产者线程,所以当有多个消费者或多生产者的情况下可以使用notifyAll()以防止程序出现“假死现象”(即线程全都处于阻塞状态),及需注意while(){wait()}的使用
具体请看以下代码
消费者与生产者一生产对多消费:
package 生产者与消费者一生产多消费队列操作;import java.util.ArrayList;import java.util.List;public class CookieList { public static final int MAX_SIZE = 1; private List<String> list = new ArrayList<String>(); public synchronized void product(){ try{ if(list.size()==MAX_SIZE) this.wait(); list.add("cookie"+((int)(Math.random()*10)+1)); System.out.println("生产者生产了"+list.get(0)); this.notify(); }catch(InterruptedException e){ } } public synchronized void customer(){ try{ //注意while while(list.size()==0) this.wait(); System.out.println("消费者消费了:"+list.get(0)); list.remove(0); this.notifyAll(); }catch(InterruptedException e){ } }}
Main
package 生产者与消费者一生产多消费队列操作;public class Main { public static void main(String[] args) { CookieList cookieList = new CookieList(); P p = new P(cookieList); C c = new C(cookieList); p.start(); c.start(); for(int i=0;i<3;++i){ c = new C(cookieList); c.start(); } } //生产者线程 public static class P extends Thread{ public CookieList cookieList; public P(CookieList cookieList){ this.cookieList = cookieList; } @Override public void run() { while(true){ this.cookieList.product(); try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); } } } } //消费者线程 public static class C extends Thread{ public CookieList cookieList; public C(CookieList cookieList){ this.cookieList = cookieList; } @Override public void run() { while(true){ this.cookieList.customer(); try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); } } } }}
消费者与生产者一消费对多生产:
package 生产者与消费者一消费多生产队列操作;import java.util.ArrayList;import java.util.List;public class CookieList { public static final int MAX_SIZE = 1; private List<String> list = new ArrayList<String>(); public synchronized void product(){ try{ while(list.size()==MAX_SIZE) this.wait(); list.add("cookie"+((int)(Math.random()*10)+1)); System.out.println("生产者生产了"+list.get(0)); this.notifyAll(); }catch(InterruptedException e){ } } public synchronized void customer(){ try{ //注意while if(list.size()==0) this.wait(); System.out.println("消费者消费了:"+list.get(0)); list.remove(0); this.notify(); }catch(InterruptedException e){ } }}
Main
package 生产者与消费者一消费多生产队列操作;public class Main { public static void main(String[] args) { CookieList cookieList = new CookieList(); P p = new P(cookieList); C c = new C(cookieList); p.start(); c.start(); for(int i=0;i<3;++i){ p = new P(cookieList); p.start(); } } //生产者线程 public static class P extends Thread{ public CookieList cookieList; public P(CookieList cookieList){ this.cookieList = cookieList; } @Override public void run() { while(true){ this.cookieList.product(); try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); } } } } //消费者线程 public static class C extends Thread{ public CookieList cookieList; public C(CookieList cookieList){ this.cookieList = cookieList; } @Override public void run() { while(true){ this.cookieList.customer(); try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); } } } }}
消费者与生产者多消费对多生产:
package 多生产多消费队列操作;import java.util.ArrayList;import java.util.List;public class CookieList { public static final int MAX_SIZE = 5; private List<String> list = new ArrayList<String>(); public synchronized void product(){ try{ while(list.size()==MAX_SIZE) this.wait(); list.add("cookie"+((int)(Math.random()*10)+1)); System.out.println("生产者生产了"+list.get(0)); this.notifyAll(); }catch(InterruptedException e){ } } public synchronized void customer(){ try{ //注意while while(list.size()==0) this.wait(); System.out.println("消费者消费了:"+list.get(0)); list.remove(0); this.notifyAll(); }catch(InterruptedException e){ } }}
Main
package 多生产多消费队列操作;public class Main { public static void main(String[] args) { CookieList cookieList = new CookieList(); P p = new P(cookieList); C c = new C(cookieList); p.start(); c.start(); for(int i=0;i<3;++i){ c = new C(cookieList); c.start(); p = new P(cookieList); p.start(); } } //生产者线程 public static class P extends Thread{ public CookieList cookieList; public P(CookieList cookieList){ this.cookieList = cookieList; } @Override public void run() { while(true){ this.cookieList.product(); try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); } } } } //消费者线程 public static class C extends Thread{ public CookieList cookieList; public C(CookieList cookieList){ this.cookieList = cookieList; } @Override public void run() { while(true){ this.cookieList.customer(); try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); } } } }}
阅读全文
2 0
- 生产者与消费者一对一,一对多,多对多
- 生产者与消费者--一对一
- 一对一,一对多,多对多,关系
- 关系:一对一、一对多,多对多。
- hibernate_一对一、一对多、多对多
- 一对一 一对多 多对多
- JPA一对一、一对多、多对多
- Hibernate一对一,一对多,多对多
- 一对多、一对一、多对多类图
- 【java多线程】【生产者与消费者】【二】【多对多】
- 一对多改成一对一
- ibatis 一对一,一对多
- MyBatis 一对一、一对多
- mybatis 一对一,一对多
- Java多线程编程4--Lock的实例--实现生产者/消费者模式:一对一、多对多交替打印
- hibernate一对一,一对多,多对一,多对多关系映射与级联
- mybatis 一对一 一对多 多对一 多对多
- 线程问题多生产者对多消费者
- POJ2492 -A Bug's Life(种类并查集)
- qt 动态添加checkbox,并添加点击事件
- hdu 1233 还是畅通工程
- Ubuntu 下 mysql的安装
- 常用Java8新特性简单介绍
- 生产者与消费者一对一,一对多,多对多
- 最大矩形面积 84 largest rectangle in histogram
- NYOJ 51. 管闲事的小明(基础题 数组标记)
- 如何快速转载CSDN中的博客
- Linux下如何查看tomcat是否启动-系统日志等
- android之.9图使用
- AngularJS Service、Factory、Provider 的理解与使用区别
- 多线程的几种实现方式(简易版)--Callable接口介绍
- Android 原生HttpURLConnection网络请求工具类(get post)