多线程系列之四: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 ...
随机推荐
- python中装饰器的原理
装饰器这玩意挺有用,当时感觉各种绕,现在终于绕明白了,俺滴个大爷,还是要慢慢思考才能买明白各种的真谛,没事就来绕一绕 def outer(func): def inner(): print(" ...
- C# json、xml序列化
json序列化: public static string SerializeJson<T>(T json) { // 1. 需要添加引用 Newtonsoft.Json.dll,默认为 ...
- win10显示许可证即将过期,但在激活界面显示的仍是已激活问题解决
win10开机显示"许可证即将过期"怎么办? 很多win10用户在开机的时候遇见了"许可证即将过期"请转到设置种激活windows的问题,但是查询自己的win1 ...
- C# -- 使用递归列出文件夹目录及目录下的文件
使用递归列出文件夹目录及目录的下文件 1.使用递归列出文件夹目录及目录下文件,并将文件目录结构在TreeView控件中显示出来. 新建一个WinForm应用程序,放置一个TreeView控件: 代码实 ...
- 【Linux基础】VI命令模式下大小写转换
[开始位置] ---- 可以指定开始的位置,默认是光标的当前位置 gu ---- 把选择范围全部小写 gU ---- 把选择范围全部大写 [结束位置] ---- 可以跟着类似的w,6G,gg等定位到错 ...
- 【漫画解读】HDFS存储原理
根据Maneesh Varshney的漫画改编,以简洁易懂的漫画形式讲解HDFS存储机制与运行原理,非常适合Hadoop/HDFS初学者理解. 一.角色出演 如上图所示,HDFS存储相关角色与功能如下 ...
- 网络协议 反扒机制 fidder 抓包工具
协议 http 协议: client 端 server 端交互的 一种形式 请求头信息: User-Agent: 情求载体的身份标识 connection: 'close' 连接状态 请求成功后 断开 ...
- centos7下安装docker(17.3docker监控---cAdvisor)
cAdvisor是google开发的容器监控工具 1.在host上运行cadvisor容器 docker run -d -p 8080:8080 --name cadvisor -v /:/rootf ...
- P1451 求细胞数量(广搜)
题意:就是0把是所有细胞圈起来了.而被圈起来的是所有数字全部为一个细胞问有多少个这样的细胞.(mmp,我读半天题) 思路:广搜索.就是,0的话就不放入了,不为0的话,就进入队列,然后,再看它的4个方向 ...
- Linux 文件系统管理
Linux 文件系统管理 课程大纲 文件系统构成及命令 硬盘分区及管理 磁盘配额 备份与恢复 文件系统构成 /usr/bin ./bin:存放所有用户可以执行的命令 /usr/s ...