多线程系列之四: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 ...
随机推荐
- Linux 中数组的使用
Linux中数组本人可能用的相对较少,但是会经常遇见,也容易忘记,就顺便记录下来吧 数值类型的数组:一对括号表示数组,数组中元素之间使用“空格”来隔开 arr=(1 2 3 4 5) 字符串类型数组: ...
- JavaScript -- 时光流逝(十二):DOM -- Element 对象
JavaScript -- 知识点回顾篇(十二):DOM -- Element 对象 (1) element.accessKey: 设置或返回accesskey一个元素,使用 Alt + 指定快捷键 ...
- JavaScript -- 时光流逝(九):Window 对象、Navigator 对象
JavaScript -- 知识点回顾篇(九):Window 对象.Navigator 对象 1. Window 对象 1.1 Window 对象的属性 (1) closed: 返回窗口是否已被关闭. ...
- Vue学习之路4-v-bind指令
1. 定义 1.1 v-bind 指令被用来响应地更新 HTML 属性,其实它是支持一个单一 JavaScript 表达式 (v-for 除外). 2. 语法 2.1 完整语法:<span v- ...
- June 16. 2018, Week 24th. Saturday
Success is the ability to go from one failure to another with no loss of enthusiasm. 成功,就是即使经历过一个又一个 ...
- ccf 再买菜 搜索 dfs
//递推关系式:(b[n-1]+b[n]+b[n+1])/3=a[n] //所以b[n+1]=3*a[n]-b[n-1]-b[n],或b[n+1]=3*a[n]-b[n-1]-b[n]+1,或b[n+ ...
- 【JXOI2018】守卫
[JXOI2018]守卫 参考题解:https://blog.csdn.net/dofypxy/article/details/80196942 大致思路就是:区间DP.对于\([l,r]\)的答案, ...
- tushare 开源数据包的使用
tushare 使用 python开源金融接口包: tushare.org/trading.html#d2 安装: pip install tushare import tushare as ts # ...
- 【转】宽带路由器应用(三)—ARP欺骗防护功能的使用
在局域网中,通信前必须通过ARP协议来完成IP地址转换为第二层物理地址(即MAC地址).ARP协议对网络安全具有重要的意义.通过伪造IP地址和MAC地址实现ARP欺骗,对网络的正常传输和安全都是一个很 ...
- Python:Day40 html
URL包括三个部分:协议.域名.路径 htyper text markup language (html) 即超文本标记语言 前端一共包括三个内容:html.css.js html做为基础,让CSS ...