多线程系列之四: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 小知识翻译 - 「syslog」
			这次聊聊「syslog」. 上次聊了「日志」(lgo).这次说起syslog,一看到log(日志)就明白是怎么回事了.syslog是获取系统日志的工具. 很多UINIX系的OS都采用了这个程序,它承担 ... 
- 【SDOI2014】向量集
			[SDOI2014]向量集 题目描述 我们分析一波: 假设我们询问\((A,B)\),\(x_i>x_j\)若 \[ A\cdot x_i+B\cdot y_i>A\cdot x_j+B\ ... 
- CSS--块级元素和行内元素
			相同:设置后,对应的模块都会脱离文档流 不同点:position相应的块级元素会覆盖下面的内容(文字,),而float只会覆盖块级元素,里面的文字会脱离 出来 float是浮动定位,position是 ... 
- UVA11584-Partitioning by Palindromes(动态规划基础)
			Problem UVA11584-Partitioning by Palindromes Accept: 1326 Submit: 7151Time Limit: 3000 mSec Problem ... 
- A. Many Equal Substrings(水题)
			思路: 直接比较橘色框里的取第一次相等,即可. #include<iostream> #include<string> using namespace std; string ... 
- springmvc中messageConverter用法
			解决StringHttpMessageConverter乱码问题问题: 当我们将字符串对象通过springmvc传回浏览器时,因为StringHttpMessageConverter消息转换器中默认的 ... 
- automake - 使用 autotools 工具集
			一般而言,对于小项目或玩具程序,手动编写 Makefile 即可.但对于大型项目,手动编写维护 Makefile 成为一件费时费力的无聊工作. 本文介绍 autotools 工具集自动生成符合 Lin ... 
- DES对称加密算法详解和c++代码实现(带样例和详细的中间数据)
			特点: 1.DES是对称性加密算法,即加密和解密是对称的,用的是同一个密钥 2.DES只处理二进制数据,所以需要将明文转换成为2进制数据 3.DES每次处理64位的数据,所以应该将明文切割成64位的分 ... 
- C++ —— 返回数组指针的函数 和 返回指向函数的指针的函数
			返回数组指针的函数 基础知识:数组不能被拷贝,函数不能返回数组,只能返回数组的指针或者引用. 定义一个 返回数组指针的函数 的方法,以 一个接收参数为 含有10个整型元素的数组的引用 和 返回一个含 ... 
- C# - Span 全面介绍:探索 .NET 新增的重要组成部分
			假设要公开特殊化排序例程,以就地对内存数据执行操作.可能要公开需要使用数组的方法,并提供对相应 T[] 执行操作的实现.如果方法的调用方有数组,且希望对整个数组进行排序,这样做就非常合适.但如果调用方 ... 
