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. LoadRunner 11 安装及破解(转)

    前提条件: 内存:2G,硬盘空闲空间10G,安装完成后实际只占不到2G 支持winXP  SP3;32位与64位win7浏览器支持IE6-8,IE9,firefox3 若以前安装过LoadRunner ...

  2. UVALive 6525

    二分图最大匹配 #include<cstdio> #include<iostream> #include<cstring> #define MAX 10010 us ...

  3. java.lang.IllegalArgumentException: Requested window android.os.BinderProxy@450b2f48 异常处理

    晕死的错误,改了半天也没想到是这样的原因,基础正要呀... 先看一下警告信息: 07-07 08:32:19.540: WARN/WindowManager(74): Failed looking u ...

  4. docker设置代理

    在天朝使用docker需要FQ. 下面给出docker的代理方式: HTTP_PROXY=http://10.167.251.83:8080 docker -d

  5. 利用vim阅读源代码一个好用的工具

    阅读源代码时常常遇到找变量,函数定义的问题.vim为我们提供了一个好用的工具,ctags. 安装 ctags. 在 libvirt的源代码根目录运行 ctags -R . vim -t virConn ...

  6. BFS 模板

    转自:欣哥 下面是bfs一般的形式,谈不上模板但一般都这么来做有点乱有什么多交流 bfs一般用于求最短时间 #include<stdio.h>#include<queue>us ...

  7. 【memcache缓存专题(1)】memcache的介绍与应用场景

    简介 Memcached是一个高性能的分布式的内存对象缓存系统,目前全世界不少人使用这个缓存项目来构建自己大负载的网站,来分担数据库的压力,通过在内存里维护一个统一的巨大的hash表,它能够用来存储各 ...

  8. Android:控件的隐藏显示

    布局中的:android:visibility 程序中可用setVisibility(); 对应的三个常量值:0.4.8 VISIBLE:0 意思是可见的INVISIBILITY:4 意思是不可见的, ...

  9. 在C#中怎么调用Resources文件中的图片

    譬如资源中有名为myPic的图片,在代码中可以这么使用: this.BackgroundImage = Properties.Resources.myPic; 如有疑问,继续追问.

  10. *EditPlus注册码在线生成

    http://www.jb51.net/tools/editplus/