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. 声明式编程思想和EEPlat

    声明式编程定义 声明式编程(英语:Declarativeprogramming)它是一种编程范式.程相对立.它描写叙述目目标性质,让计算机明白目标,而非流程. 声明式编程不用告诉电脑问题领域.从而避免 ...

  2. AsyncTask測试多任务

    本人进行过模拟測试,发现AsyncTask并不适合多任务,以及长期的异步任务,由于每次仅仅能执行一个AsyncTask,假设执行多个其他任务将会等待 以下通过一个代码样例和日志打印得到证实. 以下扩展 ...

  3. plsql dev中Dynamic Performance Tables not accessible分析解决(转)

    使用plsql dev的朋友多遇到过类此如下面的提示: Dynamic Performance Tables not accessible, Automatic Statistics Disabled ...

  4. SQL入门学习1-查询基础

    2-1 SELECT语句基础 SELECT语句作用 SELECT 语句用于从表中选取数据. 结果被存储在一个结果表中(称为结果集). 重点 使用SELECT语句从表中选取数据. 为列设定显示用的别名 ...

  5. 当一个线程进入一个对象的一个synchronized方法后,其它线程是否可进入此对象的其它方法(转)

    对象的synchronized方法不能进入了,但它的其他非synchronized方法还是可以访问的 对每一个class只有一个thread可以执行synchronized static method ...

  6. 使用exchange普通表模式被切换到分区表

    随着数据库的不断增长的数据量.有些表需要转换的普通堆表分区表模式. 有几种不同的方式来执行此操作,如出口数据表,区表再导入数据到分区表:使用EXCHANGE PARTITION方式来转换为分区表以及使 ...

  7. Google大数据三篇著名论文----中文版

    Google File System中文版 Google Bigtable中文版      Google MapReduce中文版

  8. 网站的SEO以及它和站长工具的之间秘密(转)

    博客迁移没有注意 URL 地址的变化,导致百度和 google 这两只爬虫引擎短时间内找不到路.近段时间研究了下国内最大搜索引擎百度和国际最大搜索引擎google的站长工具,说下感受. 百度的站长工具 ...

  9. Java中间MD5加密算法完整版

    携带Java软件开发过程.,因此Java中提供了自带的MessageDigest实现对文本的加密算法,以下是一个对文本进行加密的MD5加密工具类代码演示样例: package net.yuerwan. ...

  10. Linux访问Windows共享文件夹 (转)

    在开发Linux程序中,经常会使用Windows的编辑器进行编辑,这样还要拷贝到Linux服务器,如果有这种开发习惯的同学,可以使用这种方式进行开发. 当然除了这种方法之外,可以再Windows安装n ...