多线程系列之四:Guarded Suspension 模式
一,什么是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 模式的更多相关文章
- 多线程程序设计学习(4)guarded suspension模式
Guarded Suspension[生产消费者模式] 一:guarded suspension的参与者--->guardedObject(被防卫)参与者 1.1该 ...
- 多线程同步循环打印和Guarded suspension 模式
* 迅雷笔试题: * 有三个线程ID分别是A.B.C,请有多线编程实现,在屏幕上循环打印10次ABCABC… 由于线程执行的不确定性,要保证这样有序的输出,必须控制好多线程的同步. 线程同步有两种 ...
- 多线程系列之五:Balking 模式
一,什么是Balking模式 如果现在不合适执行这个操作,或者没必要执行这个操作,就停止处理,直接返回.在Balking模式中,如果守护条件不成立,就立即中断处理. 二,例子: 定期将当前数据内容写入 ...
- 并发设计模式之Guarded Suspension模式
- 原文链接: http://www.joyhwong.com/2016/11/19/并发设计模式之guarded-suspension模式/ Guarded Suspension意为保护暂停,其核心 ...
- 并行模式之Guarded Suspension模式
并行模式之Guarded Suspension模式 一).Guarded Suspension: 保护暂存模式 应用场景:当多个客户进程去请求服务进程时,客户进程的请求速度比服务进程处里请求的速度快, ...
- Guarded Suspension模式简单实现
Guarded Suspension 意为保护暂停,假设服务器很短时间内承受大量的客户端请求,客户端请求的数量超过服务器本身的即时处理能力,而服务器又不能丢弃任何一个客户端请求,此时可以让客户端的请求 ...
- 多线程系列之三:Immutable 模式
一,什么是Immutable模式?immutable就是不变的,不发生改变的.Immutable模式中存在着确保实例状态不发生变化改变的类.这些实例不需要互斥处理.String就是一个Immutabl ...
- javaScript 设计模式系列之四:组合模式
介绍 组合模式(Composite Pattern):组合多个对象形成树形结构以表示具有"整体-部分"关系的层次结构.组合模式对单个对象(即叶子对象)和组合对象(即容器对象)的使用 ...
- 多线程系列之八:Thread-Per-Message模式
一,Thread-Per-Message模式 翻译过来就是 每个消息一个线程.message可以理解为命令,请求.为每一个请求新分配一个线程,由这个线程来执行处理.Thread-Per-Message ...
随机推荐
- 学习flying logic
之前在知乎上结识的朋友吴笛,他的qq空间里分享了 flying logic的一些用途,我想到可以规划和团队的目标,这点让我感到很兴奋,分享学习这个软件. 学习之前,我应当把软件中的单词学明白.现在就 ...
- GitHub-分支管理02-BUG与Feature分支
参考博文:廖雪峰Git教程 1. Bug分支 软件开发中,bug就像家常便饭一样.有了bug就需要修复,在Git中,由于分支是如此的强大,所以,每个bug都可以通过一个新的临时分支来修复,修复后,合并 ...
- Kali 2.0 Web后门工具----WebaCoo、weevely、PHP Meterpreter
注:以下内容仅供学习使用,其他行为均与作者无关!转载请注明出处,谢谢! 本文将介绍 Kali 2.0 版本下的三款Web后门工具:WebaCoo.weevely.PHP Meterpreter,这类工 ...
- March 08th, 2018 Week 10th Thursday
Easy come, easy go. 易得则易失. Easy come, easy go, I finally undestand the phrase through somewhat hard ...
- Linux常用命令-文本查看篇
前言 Linux常用命令中,除了cat还有很多其他用于文本查看的命令.本文将简单介绍一下这些文本查看的命令. 全文本显示--cat cat可能是常用的一个文本查看命令了,使用方法也很简单: cat f ...
- 微信小程序本地引用iconfont(阿里巴巴矢量图标库)
好,忙,我懂..... 首先把图标放进项目里(废话): 接下来把这些图标下载到本地(这里不介绍网络途径了,下载就完事了) 然后利用一个网站将这个ttf文件转成base64文件https://trans ...
- python 基础操作--数据类型
一.变量 1.定义:将运算的中间结果暂存到内存,以便后续程序调用. 2.命名规则 1.变量由字母.数字.下划线搭配组合而成: 2.不可以用数字开头,也不能全都是数字: 3.不能是python 关键字, ...
- spring cloud(Greenwich.M2) hystrix dashboard 报/actuator/hystrix.stream 404 Not Found的问题
consumer端不引用spring-boot-starter-actuator的情况 Consumer端会报Unable to connect to Command Metric Stream.新建 ...
- UVA524-Prime Ring Problem(搜索剪枝)
Problem UVA524-Prime Ring Problem Accept:6782 Submit:43814 Time Limit: 3000 mSec Problem Descripti ...
- linux命令之netstat
功能:打印网络连接.路由表.接口统计信息.伪装连接和多播成员 参数 -r 显示路由表 -i 显示接口表 -n 不解析名字 -p 显示程序名 PID/Program -l 显示监听的 socket -a ...