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.yeepay.sxf.thread3;

 import java.util.LinkedList;

 /**
* 存放实体的队列
* @author sxf
*
*/
public class RequestEntryQueue {
//存放请求的链表集合
private final LinkedList<RequestEntry> list=new LinkedList<RequestEntry>(); //从队列中取出请求
public synchronized RequestEntry getRequestEntry(){
//判断存放请求的集合是否存在,请求,不存在,就让当前消费着线程进入wait set
while (list.size()<=0) {
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} }
//如果不为空,则返回第一个请求,并从集合中删除该请求
return list.removeFirst();
} //往队列中放入请求
public synchronized void putRequestEntry(RequestEntry requestEntry){
//将新的请求放入队列
list.addLast(requestEntry);
//唤醒所有wait set中的线程
notifyAll();
}
}

请求实体

 package com.yeepay.sxf.thread3;
/**
* 请求实体
* @author sxf
*
*/
public class RequestEntry {
//请求人的名字
private String name;
//线程的名字
private String clientThreadName; public RequestEntry() {
super();
} @Override
public String toString() {
// TODO Auto-generated method stub
return "["+clientThreadName+"生产线程]生产的商品"+name+"被消费";
} public RequestEntry(String name,String clientThreadName) { 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;
} }

客户端线程

 package com.yeepay.sxf.thread3;

 import java.util.Random;

 /**
* 客户端线程
* @author sxf
*
*/
public class ClientThread implements Runnable{
//存放请求的队列
private RequestEntryQueue requestEntryQueue;
//随即数
private Random random;
//线程名字
private String name; //构造器
public ClientThread(RequestEntryQueue requestEntryQueue, Random random,String name) {
super();
this.requestEntryQueue = requestEntryQueue;
this.random = random;
this.name=name;
} @Override
public void run() {
for(int i=0;i<1000;i++){
//生成一个请求
RequestEntry requestEntry=new RequestEntry("No"+i,name);
//将该请求存入队列
requestEntryQueue.putRequestEntry(requestEntry);
//让线程休息几秒
try {
Thread.sleep(random.nextInt(1000));
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} } }

服务端线程

 package com.yeepay.sxf.thread3;

 import java.util.Random;

 /**
* 服务线程
* @author sxf
*
*/
public class ServiceThread implements Runnable{
//持有存放请求的队列
private RequestEntryQueue requestEntryQueue;
//随即数
private Random random;
//线程名字
private String name; public ServiceThread(RequestEntryQueue requestEntryQueue, Random random,
String name) {
super();
this.requestEntryQueue = requestEntryQueue;
this.random = random;
this.name = name;
} @Override
public void run() {
while(true){
RequestEntry requestEntry=requestEntryQueue.getRequestEntry();
System.out.println("【消费者线程"+name+"】----------->"+requestEntry.toString()); try {
Thread.sleep(random.nextInt(1000));
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} } }

测试类

 package com.yeepay.sxf.thread3;

 import java.util.Random;

 /**
* 测试类
* @author sxf
*
*/
public class Test { public static void main(String[] args) {
//声明一个队列
RequestEntryQueue requestEntryQueue=new RequestEntryQueue();
//声明两个生产者线程
Thread clientThread1=new Thread(new ClientThread(requestEntryQueue, new Random(), "QQ客户端"));
Thread clientThread2=new Thread(new ClientThread(requestEntryQueue, new Random(), "ALIBABA客户端"));
//声明三个消费者线程
Thread serviceThread1=new Thread(new ServiceThread(requestEntryQueue, new Random(), "易宝支付"));
Thread serviceThread2=new Thread(new ServiceThread(requestEntryQueue, new Random(), "支付宝"));
Thread serviceThread3=new Thread(new ServiceThread(requestEntryQueue, new Random(), "财付通"));
//开启线程
clientThread1.start();
clientThread2.start(); serviceThread1.start();
serviceThread2.start();
serviceThread3.start(); }
}

多线程程序设计学习(4)guarded suspension模式的更多相关文章

  1. 多线程系列之四:Guarded Suspension 模式

    一,什么是Guarded Suspension模式如果执行现在的处理会造成问题,就让执行处理的线程等待.这种模式通过让线程等待来保证实例的安全性 二,实现一个简单的线程间通信的例子 一个线程(Clie ...

  2. 多线程同步循环打印和Guarded suspension 模式

     * 迅雷笔试题: * 有三个线程ID分别是A.B.C,请有多线编程实现,在屏幕上循环打印10次ABCABC…  由于线程执行的不确定性,要保证这样有序的输出,必须控制好多线程的同步. 线程同步有两种 ...

  3. 并发设计模式之Guarded Suspension模式

    - 原文链接: http://www.joyhwong.com/2016/11/19/并发设计模式之guarded-suspension模式/ Guarded Suspension意为保护暂停,其核心 ...

  4. 并行模式之Guarded Suspension模式

    并行模式之Guarded Suspension模式 一).Guarded Suspension: 保护暂存模式 应用场景:当多个客户进程去请求服务进程时,客户进程的请求速度比服务进程处里请求的速度快, ...

  5. 多线程程序设计学习(5)balking模式和timed模式

    Balking[返回模式]timed[超时模式]一:balking pattern的参与者--->GuardedObject(被警戒的对象) --->该模式的角色:模拟修改警戒对象的线程, ...

  6. 多线程程序设计学习(2)之single threaded execution pattern

    Single Threaded Execution Pattern[独木桥模式] 一:single threaded execution pattern的参与者--->SharedResourc ...

  7. Guarded Suspension模式简单实现

    Guarded Suspension 意为保护暂停,假设服务器很短时间内承受大量的客户端请求,客户端请求的数量超过服务器本身的即时处理能力,而服务器又不能丢弃任何一个客户端请求,此时可以让客户端的请求 ...

  8. 多线程程序设计学习(3)immutable pattern模式

    Immutable pattern[坚不可摧模式] 一:immutable pattern的参与者--->immutable(不变的)参与者        1.1:immutable参与者是一个 ...

  9. 多线程程序设计学习(6)Producer-Consumer模式

    Producer-Consumer[生产消费者模式]一:Producer-Consumer pattern的参与者--->产品(蛋糕)--->通道(传递蛋糕的桌子)--->生产者线程 ...

随机推荐

  1. error C2061: syntax error : identifier '__RPC__out_xcount_part'

    朋友遇到的 把dx, windows sdk ,vs2010照着成功人士的配置好 应该就可以了

  2. 输入一个字符串,内有数字和非数字字符,将其中连续的数字作为一个整数,依次存放到一数组a中。统计共有多少个整数,并输出这些数。

      #include<stdio.h> #include<stdlib.h> #include<math.h> #include<string.h> i ...

  3. java 几种常见的定时器

    今天闲着没事就总结了一下在java中常用的几种定时器. 主要有3种java.util.Timer, ScheduledExecutorService和quartz 一.Timer 举个简单例子.每隔5 ...

  4. Unity3D脚本中文系列教程(二)

    原地址:http://dong2008hong.blog.163.com/blog/static/469688272014030347910/ Unity3D脚本中文系列教程(一) .根据名称或标签定 ...

  5. Python Requests模块讲解4

    高级用法 会话对象 请求与响应对象 Prepared Requests SSL证书验证 响应体内容工作流 保持活动状态(持久连接) 流式上传 块编码请求 POST Multiple Multipart ...

  6. Palindrome Partitioning II

    Given a string s, partition s such that every substring of the partition is a palindrome. Return the ...

  7. VS2010 MFC DataGrid绑定实例

    VS2010环境下MFC使用DataGrid绑定数据源 参考:http://blog.csdn.net/fddqfddq/article/details/7874706 详细介绍如何在MFC中使用Da ...

  8. SDUT2482二叉排序树

    http://acm.sdut.edu.cn/sdutoj/showproblem.php?pid=2482&cid=1184 题目描述 二叉排序树的定义是:或者是一棵空树,或者是具有下列性质 ...

  9. Android 使用系统的Activity播放音频文件 intent

    Intent intent = new Intent(); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.setAction(Inten ...

  10. lintcode :最长单词

    题目: 最长单词 给一个词典,找出其中所有最长的单词. 样例 在词典 { "dog", "google", "facebook", &quo ...