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. j经常使用ava应用server

    什么是应用server它?它主要提供的执行环境的应用程序,为组件提供服务. 要了解更多关于,您可以查看我的博客:何为容器? Java 的应用server非常多,从功能上分为两类:WEB 应用serve ...

  2. 理解JNDI中 java:comp/env/jdbc/datasource 与 jdbc/datasource 的不同之处(转)

    在描述JNDI,例如获得数据源时,JNDI地址有两种写法,例如同是  jdbc/testDS 数据源: A:java:comp/env/jdbc/testDS B:jdbc/testDS   这两种写 ...

  3. [ngRepeat:dupes] Duplicates in a repeater are not allowed. Use &#39;track by&#39; expression to specify uniq

    angularjs 使用ng-repeat报错 <div ng-init="words = ['高校','高校','高校']" ng-repeat="word in ...

  4. jQuery EasyUI实现全部关闭tabs

    有时,当我们打开很多tabs当标签,要关闭一个接一个,它只能被关停 显然太麻烦,能够在选项卡的最右边加入一个button 实现关闭所有. 代码例如以下: <!DOCTYPE HTML PUBLI ...

  5. SQL Server 2008性能故障排查(四)——TempDB

    原文:SQL Server 2008性能故障排查(四)--TempDB 接着上一章:I/O TempDB: TempDB是一个全局数据库,存储内部和用户对象还有零食表.对象.在SQLServer操作过 ...

  6. Cocos2d-x 游戏植入广告(百度插屏)

    DEMO下载:http://download.csdn.net/detail/oyangyufu/7652803 1.声明Activity <!-- 声明百度的Activity --> & ...

  7. SQL Server 内存泄露(memory leak)——游标导致的内存问题

    原文:SQL Server 内存泄露(memory leak)--游标导致的内存问题 转自:http://blogs.msdn.com/b/apgcdsd/archive/2011/07/01/sql ...

  8. codeforces 236A . Boy or Girl(串水问题)

    A. Boy or Girl 点击打开题目 time limit per test 1 second memory limit per test 256 megabytes input standar ...

  9. ssh配置连接

    SSH构造: 1.改动vi /etc/ssh/sshd_config,依据模板将要改动的參数凝视去掉并改动參数值: Port 22 指定SSH连接的port号,安全方面不建议使用默认22port Pr ...

  10. JavaScript语言核心之词法结构

    编程语言的词法结构是一套基础性规则,用来描述如何使用这门语言来编写程序.作为语法的基础,它规定了诸如变量名是什么样的.怎么写注释,以及程序语句之间如何分割的等规则. 1.1字符集 JavaScript ...