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. setblendstate & setdepthstencilstate

    http://msdn.microsoft.com/en-us/library/windows/desktop/ff476462(v=vs.85).aspx blendstate blendfacto ...

  2. error X3025:global variables are implicitly constant, enable compatibility mode to allow modification

    global variables are implicitly constant, enable compatibility mode to allow modification http://xbo ...

  3. 解决myeclipse每次启动注册码过期输入注册码

    每次都需要重新输入一个新的注册码,搞的很不愉快,后来发现原来是因为在[我的文档]下面有一个myeclipse的配置文件,叫.myeclipse.properties 你可以全盘搜索一下这个文件,然后改 ...

  4. PE文件结构详解(三)PE导出表

    上篇文章 PE文件结构详解(二)可执行文件头 的结尾出现了一个大数组,这个数组中的每一项都是一个特定的结构,通过函数获取数组中的项可以用RtlImageDirectoryEntryToData函数,D ...

  5. 关于make: *** No rule to make target `clean'. Stop.的解决

    在重新编译makefile工程文件时需要用到 #make clean 命令, 但是最近工程使用make clean的时候总是提示: make: *** No rule to make target ` ...

  6. Consumer Client Re-Design (翻译)

    注:0.9版本Kafka的一个重大改变就是consumer和producer API的重新设计. 这篇Kafka的文档大致介绍了对于consumer API重新设计时想要实现的功能.0.9版本的确实现 ...

  7. Unity3D TestTool Part _1

    一直想看看Unity3d官方推出的UnityTestTools的测试插件,今天有空尝试了一下. 一.Quick Start 1. create a plane position which trans ...

  8. java001-Helloworld

    public class test05 { public static void main(String[] args) { System.out.println("Hello World! ...

  9. Javascript中parentNode的用法

    <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <m ...

  10. POJ 3270 Cow Sorting(置换群)

    题目链接 题意 : N头牛,每个牛的坏脾气都有一个值,每个值都不相同,把这个值按照从小到大排序,如果两个值交换,那么会花掉这两个值之和的时间,让你花最少的时间将每个值从小到大排好序,求最小的总时间. ...