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. cocos2d-x -- 渠道SDK【棱镜】接入(1)

    棱镜SDK简单介绍 若想让游戏上线,渠道接入步骤是不可缺少的,为了避免一对一接入渠道问题,我选择了棱镜SDK,由于棱镜是游戏与渠道SDK的中间层,为CP厂商屏蔽各个渠道SDK之间的差异,整个接入过程, ...

  2. hdoj 2183 奇数阶魔方(II) 【模拟】+【法】

    比赛的时候花了一个多小时,以做不做 分析:可观察:中间是(n*n+1)/2, 中间的上面是n*n,以下是1, 左边是n,右面是(n*n+1)-n,并且正对角线是最左上对到最右下端添加(+1).另外一条 ...

  3. Objective-c正确的写法单身

    Singleton模式iOS发展可能是其中最常用的模式中使用的.但是因为oc语言特性本身,想要写一个正确的Singleton模式是比较繁琐,iOS中单例模式的设计思路. 关于单例模式很多其它的介绍请參 ...

  4. Codeforces Round #267 (Div. 2) A

    题目: A. George and Accommodation time limit per test 1 second memory limit per test 256 megabytes inp ...

  5. Cloudera impala简单介绍及安装具体解释

    一.Impala简单介绍 Cloudera Impala对你存储在Apache Hadoop在HDFS,HBase的数据提供直接查询互动的SQL.除了像Hive使用同样的统一存储平台,Impala也使 ...

  6. 学习英语每日一 On the house. 赠品

    tp=webp" alt=""> On the house. 免费赠送.我们之前学过请客能够说I'll buy you something. 事实上还有一种说法是I ...

  7. 辛星整理3linux笔记,免费下载点,我希望对你有所帮助

    忙乱,这是我第一次看李指出老师的视频时,,这本书是关于116页面,在csdn下载对:点我下载 ,假设左边的地址崩溃了,也能够在浏览器中输入例如以下地址然后下载:http://download.csdn ...

  8. UnitOfWork应用

    UnitOfWork以及其在ABP中的应用 Unit Of Work(UoW)模式在企业应用架构中被广泛使用,它能够将Domain Model中对象状态的变化收集起来,并在适当的时候在同一数据库连接和 ...

  9. Instll meld in windows

    在linux下用meld感觉颇为不错,但是在windows上真是折腾老久.p4merge也试了试, 但还是meld用起来更顺手. 使用 https://wiki.gnome.org/Meld/Wind ...

  10. Oracle 11g oracle客户端(32位)PL/SQL develepment的安装配置

    Oracle 11g+oracle客户端(32位)+PL/SQL develepment的安装配置 之前一直想学Oracle,可是就是安装配置Oracle一直未成功,让人很苦恼,特别是什么监听器什么的 ...