(五)Guarded Suspension模式

一、定义

guarded是"被保护着的"、"被防卫着的"意思,suspension则是"暂停"的意思。当现在并不适合马上执行某个操作时,就要求想要执行该操作的线程等待,这就是Guarded Suspension Pattern,会要求线程等候,以保障实例的安全性,其它类似的称呼还有guarded wait、spin lock等。

 

二、模式案例

下面的案例是一种简单的消息处理模式,客户栈线程发起请求,有请求队列缓存请求,然后发送给服务端线程进行处理。

 

//Request类表示请求
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 final LinkedList<Request> queue = new LinkedList<Request>();

    public synchronized Request getRequest(){
        while(queue.size()<=0){
            try{
                wait();
            }catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        return (Request) queue.removeFirst();
    }

    public synchronized void putRequest(Request request){
        queue.addLast(request);
        notifyAll();
    }
}
//客户端线程不断生成请求,插入请求队列
public class ClientThread extends Thread{
    private Random random;
    private RequestQueue requestQueue;

    public ClientThread(RequestQueue requestQueue,String name,long seed) {
        super(name);
        this.requestQueue = requestQueue;
        this.random = new Random(seed);
    }

    public void run() {
        for(int i=0;i<10000;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) {
                e.printStackTrace();
            }
        }
    }
}
//服务端线程类不断从请求队列中获取请求,然后处理请求
public class ServerThread extends Thread{
    private Random random;
    private RequestQueue requestQueue;

    public ServerThread(RequestQueue requestQueue,String name,long seed) {
        super(name);
        this.requestQueue = requestQueue;
        this.random = new Random(seed);
    }

    @Override
    public void run() {
        for(int i=0;i<10000;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 Main {
    public static void main(String[] args) {
        RequestQueue requestQueue = new RequestQueue();
        new ClientThread(requestQueue,"Alice",3141592L).start();
        new ServerThread(requestQueue,"Boddy",6535897L).start();
    }
}

 

三、模式讲解

角色:

Guarded Suspension Pattern的角色如下:

  • GuardedObject(被防卫的对象)参与者

GuardedObject参与者是一个拥有被防卫的方法(guardedMethod)的类。当线程执行guardedMethod时,只要满足警戒条件,就能继续执行,否则线程会进入wait set区等待。警戒条件是否成立随着GuardedObject的状态而变化。

GuardedObject参与者除了guardedMethod外,可能还有用来更改实例状态的方法stateChangingMethod。

在Java语言中,是使用while语句和wait方法来实现guardedMethod的;使用notify/notifyAll方法实现stateChangingMethod。如案例中的RequestQueue类。

注意:Guarded Suspension Pattern需要使用while,这样可以使从wait set被唤醒的线程在继续向下执行前检查Guard条件。如果改用if,当多个线程被唤醒时,由于wait是继续向下执行的,可能会出现问题。

 

 

 

借鉴学习自https://segmentfault.com/a/1190000015558615

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值