一,什么是Guarded Suspension模式
如果执行现在的处理会造成问题,就让执行处理的线程等待。这种模式通过让线程等待来保证实例的安全性

二,实现一个简单的线程间通信的例子

一个线程(ClientThread)将请求(Request)的实例传递给另外一个线程(ServerThread)

Request:线程实例

RequestQueue:存放请求(Request)实例的队列

ClientThread:把线程实例放到队列中

ServerThread:从队列中取线程示例

示例程序

public class Request {

    private final String name;

    public Request(String name) {
this.name = name;
} public String getName() {
return name;
} @Override
public String toString() {
return "Request{" +
"name='" + name + '\'' +
'}';
}
}
public class RequestQueue {
private Queue<Request> queue = new LinkedList<>();
public synchronized void putRequest(Request request){
queue.offer(request);
notifyAll();
}
public synchronized Request getRequest(){
while (queue.peek() == null){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return queue.remove();
} }
public class ClientThread extends Thread {
private final Random random;
private final RequestQueue requestQueue; public ClientThread(RequestQueue requestQueue,String name ,long seed){
super(name);
this.random = new Random(seed);
this.requestQueue = requestQueue;
} @Override
public void run() {
for (int i = 0; i < 10000; i++) {
Request request = new Request("N0."+i);
System.out.println(Thread.currentThread().getName()+" requests "+request);
requestQueue.putRequest(request);
try {
Thread.sleep(random.nextInt(1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class ServerThread extends Thread{
private final Random random;
private final RequestQueue requestQueue; public ServerThread(RequestQueue requestQueue,String name,long seed){
super(name);
this.random = new Random(seed);
this.requestQueue =requestQueue;
} @Override
public void run() {
for (int i = 0; i < 1000; i++) {
Request request = requestQueue.getRequest();
System.out.println(Thread.currentThread().getName()+" handles "+request);
try {
Thread.sleep(random.nextInt(1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class Test {
public static void main(String[] args) {
RequestQueue requestQueue = new RequestQueue();
new ClientThread(requestQueue,"Alice",3141592L).start();
new ServerThread(requestQueue,"Bobby",6583184L).start();
}
}

三,Guarded Suspension模式中的登场角色

GuardedObject:被守护的对象
GuardedObject是一个持有被守护的方法(guardedMethod)的类,当线程执行guardedMethod方法时,若守护条件成立,则可以立刻执行,
当守护条件不成立,就要进行等待。
守护条件的成立与否和被守护对象的状态有关。
所以在上面的示例程序中
RequestQueue:就是被守护对象
getRequest方法:就是被守护方法
putRequest方法:改变状态的方法

四,wait和notify/notifyAll的责任

上面的示例程序中,我们把wait/notifyAll都写在了RequestQueue类中,并没有出现在ClientThread,ServerThread,Main类中。
Guarded Suspension模式的实现封装在RequestQueue类中。
这种将wait/notifyAll隐藏起来的做法对RequestQueue类的复用性非常重要。当我们在使用RequestQueue时,其他类无需考虑wait,notifyAll的问题,
只要调用getRequest方法或putRequst方法就行。

五,使用java.util.concurrent.LinkedBlockingQueue的示例程序

这个类和RequestQueue类功能相同。该类中的take方法用于 取出队首元素,put方法则用于向队列末尾添加元素。当队列为空时,若调用take方法便会进行wait,
并且take和put已经考虑了互斥处理。所以getRequest和putRequest方法就无需声明为synchronized了。LinkedBlockingQueue类中使用了Guarded Suspension模式。

代码:

public class RequestQueue {

    private final BlockingQueue<Request> queue = new LinkedBlockingQueue<>();

    public void putRequest(Request request){
try {
queue.put(request);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public Request getRequest(){
Request request = null;
try {
request = queue.take();
} catch (InterruptedException e) {
e.printStackTrace();
}
return request;
}
}

多线程系列之四:Guarded Suspension 模式的更多相关文章

  1. 多线程程序设计学习(4)guarded suspension模式

    Guarded Suspension[生产消费者模式] 一:guarded suspension的参与者--->guardedObject(被防卫)参与者                1.1该 ...

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

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

  3. 多线程系列之五:Balking 模式

    一,什么是Balking模式 如果现在不合适执行这个操作,或者没必要执行这个操作,就停止处理,直接返回.在Balking模式中,如果守护条件不成立,就立即中断处理. 二,例子: 定期将当前数据内容写入 ...

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

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

  5. 并行模式之Guarded Suspension模式

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

  6. Guarded Suspension模式简单实现

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

  7. 多线程系列之三:Immutable 模式

    一,什么是Immutable模式?immutable就是不变的,不发生改变的.Immutable模式中存在着确保实例状态不发生变化改变的类.这些实例不需要互斥处理.String就是一个Immutabl ...

  8. javaScript 设计模式系列之四:组合模式

    介绍 组合模式(Composite Pattern):组合多个对象形成树形结构以表示具有"整体-部分"关系的层次结构.组合模式对单个对象(即叶子对象)和组合对象(即容器对象)的使用 ...

  9. 多线程系列之八:Thread-Per-Message模式

    一,Thread-Per-Message模式 翻译过来就是 每个消息一个线程.message可以理解为命令,请求.为每一个请求新分配一个线程,由这个线程来执行处理.Thread-Per-Message ...

随机推荐

  1. 4.10Python数据处理篇之Matplotlib系列(十)---文本的显示

    目录 目录 前言 (一)中文显示 ==1.全局的设置== ==2.局部的设置== (二)文本显示 目录 前言 今天我们来学习一下文本的显示 (一)中文显示 ==1.全局的设置== (1)说明: 在ma ...

  2. Ubuntu16.04下iTop4412环境搭建+Android4.0.3编译

    系统:Ubuntu16.04.02(优麒麟) 安装库文件和JDK 使用cd 命令,进入解压出来的“Android_JDK” -->“jdk6”文件夹,运行脚本文件 “install-sun-ja ...

  3. SQLServer数据库增删改查

    一.数据库定义 数据库(Database)是按照数据结构来组织.存储和管理数据的仓库.数据库的操作分为两种形式:一种是直接在数据库管理工具图形化界面进行操作:一种是使用数据库脚本进行操作,数据库脚本可 ...

  4. react中使用Ajax请求(axios,Fetch)

    React本身只关注于界面, 并不包含发送ajax请求的代码,前端应用需要通过ajax请求与后台进行交互(json数据),可以使用集成第三方ajax库(或自己封装) 常用的ajax请求库 jQuery ...

  5. springboot统一异常处理类及注解参数为数组的写法

    统一异常处理类 package com.wdcloud.categoryserver.common.exception; import com.wdcloud.categoryserver.commo ...

  6. UVA10603-Fill(BFS)

    Problem UVA10603-Fill Accept:1162  Submit:10693 Time Limit: 3000 mSec  Problem Description There are ...

  7. php实现TXT小说章节解析、小说章节在线阅读

    每天学习一点点 编程PDF电子书.视频教程免费下载:http://www.shitanlife.com/code 要实现TXT文本章节的解析,大概思路是在每个章节加入了特定的字符,然后根据字符的起始位 ...

  8. 微信硬件平台(七) 设备控制控制面板-网页sokect-mqtt长连接

    给微信硬件设备添加我们自己的控制面板. 主要问题: 1 要保证长连接,这样面板可以实时交互阴间设备,http一次性的连接模式通信不行. 面板必须是网页化的,网页就可以操作交互.不用APP和小程序. 2 ...

  9. docker 11 docker的commit操作

    docker commit :表示提交一个容器的副本使之成为新的镜像.假如我们在docker上运行了一个tomcat的容器,对Tomcat容器进行了修改操作,然后我们将修改操作后的tomcat进行co ...

  10. 区分range() , np.arange() , np.linspace()

    content: range() np.arange() np.linspace() 一.range(start, stop, step) 1.range() 为 python 自带函数 2.生成一个 ...