多线程学习之三生产者消费者模式Guarded Suspension
Guarded Suspension【生产消费者模式】
一:guarded suspension的参与者
--->guardedObject(被防卫)参与者
1.1该参与者拥有一个被防卫的方法(getRequest),如果警戒条件达成,则执行。警戒条件不达成,则线程进入wait set
1.2该参与者还拥有一个改变参与者状态的方法(putRequest)。参与者的状态影响着警戒条件的是否达成。
--->该模式的角色:生产端线程,消费端线程,传递数据的摇篮(被防卫的参与者)
二:guarded suspension模式什么时候使用
--->适合交易系统使用。客户端下单,服务端处理订单。高并发,大量数据处理的模式,增强服务的吞吐量
三:guarded suspension思考
--->与该模式共通的三个特征
3.1:有循环存在
3.2:有条件测试
3.3:有因某种原因的等待
---> guarded wait 被阻断而等待
等待端范例:
while(条件){
wait();
}
唤醒端范例:
条件=true
notifyAll();
---> busy wait 忙碌地等待
yield,尽可能把优先级交给其他线程,那个线程调用此方法,那个线程暂时一次让出CPU调度权。至于能否暂停,实际看cpu是否去掉别的线程。我主动
放弃一次,至于cpu走不走,看cpu的。yield不会解除锁定,所以这段代码不可写在snychronized里。而ready字段必须声明成
volatile
等待端范例:
while(ready){
Thead.yield();
}
唤醒端范例:
ready=true
---> spin lock 旋转而锁定
旋转而锁定的意思,表现出条件成立前while循环不断"旋转"的样子,spin lock有时意思与guarded wait相同,有时则与busy
wait相同。另外,有时候则是指一开始使用busy wait ,之后再切换成guarded wait方式。另外有些硬件实现的同步机制
--->polling
" 进行舆论调查"的意思,反复检查某个事件是否发生,当发生时就进行对应的处理。
请求实体类
/**
*
*/
package com.benxq.thread4; /**
* 模拟请求实体
* Created by qucf on 2015年10月22日.
*/
public class RequestEntity { //请求人的名称
private String name; //线程的名称
private String clientThreadName; public RequestEntity() {
super();
} /**
* @param name
* @param clientThreadName
*/
public RequestEntity(String name, String clientThreadName) {
super();
this.name = name;
this.clientThreadName = clientThreadName;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public String getClientThreadName() {
return clientThreadName;
} public void setClientThreadName(String clientThreadName) {
this.clientThreadName = clientThreadName;
} @Override
public String toString() {
return "生产者:"+clientThreadName+"生产者生产的产品"+name+"被消费";
}
}
请求实体队列类
/**
*
*/
package com.benxq.thread4; import java.util.LinkedList; /**
* 模拟请求队列
* Created by qucf on 2015年10月22日.
*/
public class RequestQueue { //模拟队列容器
private LinkedList<RequestEntity> list=new LinkedList<RequestEntity>(); //从队列中取出数据
public synchronized RequestEntity getRequestEntity(){
//当容器中的数据为0时进入等待状态
while(list.size()<=0){
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//如果不为空,返回第一个请求,并从集合中删除该请求
return list.removeFirst();
} //往队列中加入数据
public synchronized void putRequestEntity(RequestEntity entity){
//将加入的数据加入队列尾部
list.addLast(entity);
//唤醒所有的线程
notifyAll();
} }
生产线程
/**
*
*/
package com.benxq.thread4; import java.util.Random; /**
* 模拟请求线程
* Created by qucf on 2015年10月22日.
*/
public class ClientThread implements Runnable{ //存放请求的队列
private RequestQueue queue; //随机数
private Random random; //线程名称
private String name; /**
* @param queue
* @param random
* @param name
*/
public ClientThread(RequestQueue queue, Random random, String name) {
super();
this.queue = queue;
this.random = random;
this.name = name;
} @Override
public void run() { for (int i = 0; i < 5; i++) {
//生成一个请求
RequestEntity entity=new RequestEntity("No"+i, name); //将请求放入到队列中
queue.putRequestEntity(entity); //让线程休息几秒
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
消费线程
/**
*
*/
package com.benxq.thread4; import java.util.Random; /**
* 消费线程
* Created by qucf on 2015年10月22日.
*/
public class ServiceThread implements Runnable{ //持有线程的队列
private RequestQueue queue;
//随机数
private Random random;
//线程名
private String name; @Override
public void run() {
while(true){
RequestEntity entiry=queue.getRequestEntity();
System.out.println("消费线程"+name+"----->"+entiry.toString());
try {
Thread.sleep(random.nextInt(random.nextInt(1000)));
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
} /**
* @param queue
* @param random
* @param name
*/
public ServiceThread(RequestQueue queue, Random random, String name) {
super();
this.queue = queue;
this.random = random;
this.name = name;
} }
主线程
/**
*
*/
package com.benxq.thread4; import java.util.Random; /**
* 主线程
* Created by qucf on 2015年10月22日.
*/
public class Test { public static void main(String[] args) {
//声明一个队列
RequestQueue queue=new RequestQueue(); //生产者线程
Thread sc1=new Thread(new ClientThread(queue, new Random(), "QQ客户端"));
Thread sc2=new Thread(new ClientThread(queue, new Random(), "ALIBABA客户端")); //消费者线程
Thread xf1=new Thread(new ServiceThread(queue, new Random(), "渠道1"));
Thread xf2=new Thread(new ServiceThread(queue, new Random(), "渠道2"));
Thread xf3=new Thread(new ServiceThread(queue, new Random(), "渠道3")); //开启线程
sc1.start();
sc2.start(); xf1.start();
xf2.start();
xf3.start();
}
}
多线程学习之三生产者消费者模式Guarded Suspension的更多相关文章
- java 多线程 22 :生产者/消费者模式 进阶 利用await()/signal()实现
java多线程15 :wait()和notify() 的生产者/消费者模式 在这一章已经实现了 wait/notify 生产消费模型 利用await()/signal()实现生产者和消费者模型 一样 ...
- Celery 框架学习笔记(生产者消费者模式)
生产者消费者模式 在实际的软件开发过程中,经常会碰到如下场景:某个模块负责产生数据,这些数据由另一个模块来负责处理(此处的模块是广义的,可以是类.函数.线程.进程等).产生数据的模块,就形象地称为生产 ...
- Java多线程学习笔记--生产消费者模式
实际开发中,我们经常会接触到生产消费者模型,如:Android的Looper相应handler处理UI操作,Socket通信的响应过程.数据缓冲区在文件读写应用等.强大的模型框架,鉴于本人水平有限目前 ...
- JAVA多线程编程之生产者消费者模式
Java中有一个BlockingQueue可以用来充当堵塞队列,下面是一个桌面搜索的设计 package net.jcip.examples; import java.io.File; import ...
- .net学习之多线程、线程死锁、线程通信 生产者消费者模式、委托的简单使用、GDI(图形设计接口)常用的方法
1.多线程简单使用(1)进程是不执行代码的,执行代码的是线程,一个进程默认有一个线程(2)线程默认情况下都是前台线程,要所有的前台线程退出以后程序才会退出,进程里默认的线程我们叫做主线程或者叫做UI线 ...
- 2.5多线程(Java学习笔记)生产者消费者模式
一.什么是生产者消费者模式 生产者生产数据存放在缓冲区,消费者从缓冲区拿出数据处理. 可能大家会问这样有何好处? 1.解耦 由于有了缓冲区,生产者和消费者之间不直接依赖,耦合度降低,便于程序拓展和维护 ...
- java 多线程并发系列之 生产者消费者模式的两种实现
在并发编程中使用生产者和消费者模式能够解决绝大多数并发问题.该模式通过平衡生产线程和消费线程的工作能力来提高程序的整体处理数据的速度. 为什么要使用生产者和消费者模式 在线程世界里,生产者就是生产数据 ...
- 【多线程】--生产者消费者模式--Lock版本
在JDK1.5发布后,提供了Synchronized的更优解决方案:Lock 和 Condition 我们使用这些新知识,来改进例子:[多线程]--生产者消费者模式--Synchronized版本 改 ...
- java+反射+多线程+生产者消费者模式+读取xml(SAX)入数据库mysql-【费元星Q9715234】
java+反射+多线程+生产者消费者模式+读取xml(SAX)入数据库mysql-[费元星Q9715234] 说明如下,不懂的问题直接我[费元星Q9715234] 1.反射的意义在于不将xml tag ...
随机推荐
- Play Modules Morphia 1.2.9a 之 Aggregation and Group aggregation
聚合 和 分组聚合: PlayMorphia 它提供了基于开发人员models的友好接口 设想你定义了一个model.class Sales: @Entity public class Sales e ...
- 第二章_session管理
2.1 URL重写 URL重写是Session追踪技术.须要将一个或多个token做为一个查询字符串加入到一个URL中. Token的格式通常是键=值. Url?key-1=value-1&k ...
- python在windows通过安装模块错误
我的环境是win7+vs2013+python3.2,他们是32地点 windows通过安装模块错误 1)Unable to find vcvarsall.bat : 打开"<pyth ...
- Java 信号 Semaphore 简介
Semaphore当前在多线程环境下被扩放使用.操作系统的信号量是个非常重要的概念,在进程控制方面都有应用. Java 并发库 的Semaphore 能够非常轻松完毕信号量控制,Semaphore能够 ...
- ios 类似的效果淘宝商品详细页面
今天试着写ios 分类似影响淘宝的商品详细页面 我使用第三方库EGORefreshTableHeaderView有一个下拉效果刷新PWLoadMoreTableFooterView上拉电阻负载许多其他 ...
- swift 笔记 (十九) ——
协议
协议(Protocols) 协议仅是用定义某些任务或者是功能必须的方法和属性. 类似于java里的interface的作用.但协议并不会实现详细的功能. 我猜这个名字源于OO中提到的"契约& ...
- SICP 习题(1.1,1.2,1.3,1.4)解题总结。
近来在重读SICP,以前读过一次,读了第一二章就没有坚持下去,时间一长就基本忘记了,脑海里什么都不剩,就隐约记得自己曾经读过一本很牛B的书. 这次读希望能够扎实一点,不管能读到哪里,希望可以理解一些东 ...
- myeclipse解决JSP文件script调整背景颜色
1进口MyEclipse主题后,打开jsp要么html文件,jsvascript部分原因遭遇了一层白色的.闪避这个时候.症状,如下面: watermark/2/text/aHR0cDovL2Jsb2c ...
- Linux Howto
1. Customize the Xfce menu http://wiki.xfce.org/howto/customize-menu
- NYOJ 904 search(stable_sort函数的应用)
描述 游戏积分的排行榜出来了,小z想看看得某个积分的人是谁.但是由于人数很多,他自己找很浪费时间,所以他想请你帮忙写一个程序,能快速的帮他找到他想要找的人 输入 多组测试数据,第一行有一个数T,表 ...