java多线程之Guarded Suspension模式
Guarded Suspension模式(等我准备好哦)
在Single Threaded Execution模式中,只要有一个线程进入临界区,其他线程就无法进入,只能等待。而在Guarded Suspension模式中,线程是否等待取决于守护条件。Guarded Suspension模式是在Single Threaded Execution模式的基础上附加了条件而形成的。
如下一段代码实例:
request用于表示请求,表示ClientThread传递给ServerThread的实例
public class Request {
private final String name;
public Request(String name) {
super();
this.name = name;
}
public String getName() {
return name;
}
public String toString(){
return "[Request"+ name+"]";
}
}
RequestQueue类用于依次存放请求,类中定义了getRequest方法和putRequest方法
getRequest方法会取出最先存放在requestQueue中的一个请求,作为其返回值。如果一个请求都没有,那么就一直等待,直到其他线程执行putRequest
putRequest方法用于添加一个请求。当线程想要向RequestQueue中添加Request实例时,可以调用该实例方法。
public class RequestQueue {
private final Queue<Request> queue = new LinkedList<Request>();
public synchronized Request getRequest(){
while(queue.peek()==null){//守护条件
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return queue.remove();
}
public synchronized void putRequest(Request request){
queue.offer(request);
notifyAll();
}
}
CientThread 类用于表示发送请求的线程。ClientThread持有RequestQueue的实例,并连续调用该实例的putRequest,放入请求,请求的名称依次为NO1,NO2.....
为了错开发送请求的时间点,使用random随机生成了0到1000之间的数,来作为sleep的时间(以毫秒为单位)
public class ClientThread extends Thread{
private final Random random;
private final RequestQueue requestQueue;
public ClientThread(RequestQueue requestQueue,String name,long seed){
this.requestQueue = requestQueue;
this.random = new Random(seed);
}
public void run(){
for (int i = 0; i < 1000; i++) {
Request request = new Request("No."+i);
System.out.println(Thread.currentThread().getName()+"request:"+request);
requestQueue.putRequest(request);
try {
Thread.sleep(random.nextInt(1000));
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
ServerThread类用于表示接收请求的线程。该类持有RequestQueue的实例 (requestQueue).
ServerThread使用getRequest方法接收请求
public class ServerThread extends Thread{
private final Random random;
private final RequestQueue requestQueue;
public ServerThread(RequestQueue requestQueue,String name,long seed){
this.requestQueue = requestQueue;
this.random = new Random(seed);
}
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) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
Main类会首先创建RequestQueue的实例(requestQueue),然后分别创建名为Alice的实例ClientThread和名为Boddy的实例ServerThread,并将requestQueue传给这两个实例,最后执行start.
public class Main {
public static void main(String[] args) {
RequestQueue requestQueue = new RequestQueue();
new ClientThread(requestQueue, "Alice", 3141592L).start();;
new ClientThread(requestQueue, "Bobby", 6535897L).start();;
}
}
GuardedObject 角色是一个持有被守护的方法的类.当线程执行guardedMethod方法时,如果条件成立,则可以立即执行,当守护条件不成立,则进行等待。
三大特征:
存在循环
存在条件检查
因为某种原因而等待
guarded supension :被守护而暂停执行的含义
guarded wait:被守护而等待
采用LinkedBlockingQueue时,实例程序中的RequestQueue可以被简化。
take方法用于取出队首的元素(将队头元素出队,如果队列空了,一直阻塞,直到队列不为空或者线程被中断),put方法用于向队列末尾添加元素(在队尾插入一个元素,如果队列满了,一直阻塞,直到队列不满了或者线程被中断)。这两个方法都进行了封装。因为这两个方法已经考虑了互斥的方法,所以无需声明为synchroized方法。
public class RequestQueue {
private final BlockingQueue<Request> queue = new LinkedBlockingQueue<Request>();
public Request getRequest(){
Request req = null;
try {
req = queue.take();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}//取出队首元素
return req;
}
public void putRequest(Request request){
try {
queue.put(request);//向队列末尾添加元素
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
LinkedList和LinkedBlockingQueue的比较
对于Guarded Supension模式的总结:
该模式存在一个持有状态的对象,只有在这个对象的状态满足条件的情况下,才会允许现在执行目标处理。所以,我们先将这个对象的满足条件作为它的“守护条件”,然后,在执行这个目标处理之前,检查守护条件是否成立,只有当守护条件成立时,线程才会执行目标处理,而当守护条件不成立时,线程就会一直等到成立为止,使用while条件嵌套检查条件,wait()执行等待,使用notifyAll()方法进行通知。这就是Guarded Suspension模式。
java多线程之Guarded Suspension模式相关推荐
- Java并发编程实战~Guarded Suspension模式
Guarded Suspension 模式 比如,项目组团建要外出聚餐,我们提前预订了一个包间,然后兴冲冲地奔过去,到那儿后大堂经理看了一眼包间,发现服务员正在收拾,就会告诉我们:"您预订的 ...
- java暂挂状态,Guarded Suspension(保护性暂挂)模式
思维导图 思维导图 Guarded Suspension 模式简介 Guarded Suspension 模式的核心是一个受保护方法(Guarded Method).该方法在执行其所需要真正执行的操作 ...
- 并发设计模式之Guarded Suspension模式
- 原文链接: http://www.joyhwong.com/2016/11/19/并发设计模式之guarded-suspension模式/ Guarded Suspension意为保护暂停,其核心 ...
- 实战并发编程 - 08基于Guarded Suspension模式优化轮询while(true)
文章目录 Guarded Suspension模式简介 看牙医的就诊流程 代码举例 总结与拓展 Guarded Suspension模式简介 guarded在这里是"保护"的意思: ...
- JAVA多线程之wait/notify
本文主要学习JAVA多线程中的 wait()方法 与 notify()/notifyAll()方法的用法. ①wait() 与 notify/notifyAll 方法必须在同步代码块中使用 ②wait ...
- Java多线程之Callable、Future和FutureTask
Java多线程之Callable接口 自己想总结一下的,看到一篇总结的更好的博客,就转载了,突然感觉真轻松,哈哈哈哈 文章转载于:Matrix海子:Java并发编程:Callable.Future和F ...
- Java多线程之Synchronized和Lock的区别
Java多线程之Synchronized和Lock的区别 目录: 原始构成 使用方法 等待是否可以中断 加锁是否公平 锁绑定多个条件Condition 小结:Lock相比较Synchronized的优 ...
- Java多线程之CAS缺点
Java多线程之CAS缺点 目录: 循环时间开销很大 只能保证一个共享变量的原子操作 引来ABA问题及解决方案(重点) 1. 循环时间开销很大 通过看源码,我们发现有个do while,如果CAS失败 ...
- Java多线程之CAS深入解析
Java多线程之CAS深入解析 目录: CAS是什么 CAS底层原理Unsafe深入解析 CAS缺点 引子:蚂蚁花呗一面:讲一讲AtomicInteger,为什么要用CAS而不是synchronize ...
- Java多线程之volatile详解
Java多线程之volatile详解 目录: 什么是volatile? JMM内存模型之可见性 volatile三大特性之一:保证可见性 volatile三大特性之二:不保证原子性 volatile三 ...
最新文章
- 操作dict时避免出现KeyError的几种方法
- matlab生成有向网络,matlab ode45和矩阵生成有向网络图
- uboot中关于LCD的代码分析
- POJ 3461Oulipo KMP模板
- for jq 嵌套_遍历嵌套列表 – jQuery
- 特斯拉在以色列开售Model 3 比国内贵出30%!
- 微信抢红包算法 java_java 实现仿照微信抢红包算法,实测结果基本和微信吻合,附demo...
- ubuntu配置fastdfs+Nginx
- 解决Windows Vista/7/8/8.1 远程桌面连接XP或2003缓慢的问题
- Unity-遮挡剔除
- c语言 dfs,DFS(深度优先搜索)
- sql中日期转化为各種字符串格式
- AGV自导航机器人执行的安全标准
- 【ps功能精通】1.简单了解PS
- 【HLS教程】HLS入门与精通
- Win10 下安装 MSYS2
- 在html中插入层,网页制作问题-在背景上添加一个或多个层(也就是层叠)是怎么做的?...
- 进程间通信之面包师问题
- 取消Vue中格式警告
- 【CentOS7安装Redis及常用命令】