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的更多相关文章

  1. java 多线程 22 :生产者/消费者模式 进阶 利用await()/signal()实现

    java多线程15 :wait()和notify() 的生产者/消费者模式 在这一章已经实现了  wait/notify 生产消费模型 利用await()/signal()实现生产者和消费者模型 一样 ...

  2. Celery 框架学习笔记(生产者消费者模式)

    生产者消费者模式 在实际的软件开发过程中,经常会碰到如下场景:某个模块负责产生数据,这些数据由另一个模块来负责处理(此处的模块是广义的,可以是类.函数.线程.进程等).产生数据的模块,就形象地称为生产 ...

  3. Java多线程学习笔记--生产消费者模式

    实际开发中,我们经常会接触到生产消费者模型,如:Android的Looper相应handler处理UI操作,Socket通信的响应过程.数据缓冲区在文件读写应用等.强大的模型框架,鉴于本人水平有限目前 ...

  4. JAVA多线程编程之生产者消费者模式

    Java中有一个BlockingQueue可以用来充当堵塞队列,下面是一个桌面搜索的设计 package net.jcip.examples; import java.io.File; import ...

  5. .net学习之多线程、线程死锁、线程通信 生产者消费者模式、委托的简单使用、GDI(图形设计接口)常用的方法

    1.多线程简单使用(1)进程是不执行代码的,执行代码的是线程,一个进程默认有一个线程(2)线程默认情况下都是前台线程,要所有的前台线程退出以后程序才会退出,进程里默认的线程我们叫做主线程或者叫做UI线 ...

  6. 2.5多线程(Java学习笔记)生产者消费者模式

    一.什么是生产者消费者模式 生产者生产数据存放在缓冲区,消费者从缓冲区拿出数据处理. 可能大家会问这样有何好处? 1.解耦 由于有了缓冲区,生产者和消费者之间不直接依赖,耦合度降低,便于程序拓展和维护 ...

  7. java 多线程并发系列之 生产者消费者模式的两种实现

    在并发编程中使用生产者和消费者模式能够解决绝大多数并发问题.该模式通过平衡生产线程和消费线程的工作能力来提高程序的整体处理数据的速度. 为什么要使用生产者和消费者模式 在线程世界里,生产者就是生产数据 ...

  8. 【多线程】--生产者消费者模式--Lock版本

    在JDK1.5发布后,提供了Synchronized的更优解决方案:Lock 和 Condition 我们使用这些新知识,来改进例子:[多线程]--生产者消费者模式--Synchronized版本 改 ...

  9. java+反射+多线程+生产者消费者模式+读取xml(SAX)入数据库mysql-【费元星Q9715234】

    java+反射+多线程+生产者消费者模式+读取xml(SAX)入数据库mysql-[费元星Q9715234] 说明如下,不懂的问题直接我[费元星Q9715234] 1.反射的意义在于不将xml tag ...

随机推荐

  1. 【转】MAT(Memory Analyzer Tool)工具入门介绍

    1.MAT是什么? MAT(Memory Analyzer Tool),一个基于Eclipse的内存分析工具,是一个快速.功能丰富的JAVA heap分析工具,它可以帮助我们查找内存泄漏和减少内存消耗 ...

  2. SPOJ SUBLEX 7258. Lexicographical Substring Search

    看起来像是普通的SAM+dfs...但SPOJ太慢了......倒腾了一个晚上不是WA 就是RE ..... 最后换SA写了...... Lexicographical Substring Searc ...

  3. D3D 扎带 小样本

    D3D 符合基本程序 #pragma once #pragma comment(lib,"d3d9.lib") #pragma comment(lib,"d3dx9.li ...

  4. 接口设计ie常见的问题

    问题叙述性说明: 当围绕一个简单的页面布局设计.我发现了一个奇怪的相对布局问题. 同的方式围绕布局接口.它是利用左div浮动.对div设定 margin-left这样达到的效果.实现了chrome浏览 ...

  5. 深入浅出java并发

    http://www.blogjava.net/xylz/archive/2010/07/08/325587.html

  6. UIBezierPath 和 CAShapeLayer 绘画图纸

    五角大楼画一个小圆圈戴: - (void)drawPentagon{ //(1)UIBezierPath对象 UIBezierPath *aPath = [UIBezierPath bezierPat ...

  7. windows(64位)下用vagrant+virtualbox 管理虚拟机具体解释

    windows下安装(64位) vagrant 跟 vituriebox http://blog.smdcn.net/article/1308.html Host: 127.0.0.1 Port: 2 ...

  8. 【iOS发展-28】制造业UITabBarController标记控制器、定制UITabBarItem文字图像6途径和More评论

    一个.一个简单的制作过程(实际工程中不建议这样的方式,不要只展示所用原理的理解) 在AppDelegate.m在: - (BOOL)application:(UIApplication *)appli ...

  9. hdu 1150 Machine Schedule (经典二分匹配)

    //A组n人 B组m人 //最多有多少人匹配 每人仅仅有匹配一次 # include<stdio.h> # include<string.h> # include<alg ...

  10. hdu4453 Looploop 2012年杭州现场赛 Splay

    题意:维护一个圈,实现六个功能,给某位置起的一些数增加某值,反转某一段数,添加删除某些数,移动当前所指的位置, 简单的splay,把圈拆成链,对于每种操作,处理一下. #define inf 0x3f ...