多线程编程模式之Guarded Suspension模式

Guarded Suspension

Guarded Suspension模式介绍

如果执行现在的处理会造成问题,就让执行的线程进行等待,Guarded Suspension 模式是通过让线程等待来保护实例的安全性,即守护-挂起模式;

Guarded Suspension 模式的使用场景

  1. 多线程环境下多个线程访问相同实例资源,从实例资源中获得资源并处理;
  2. 实例资源需要管理自身拥有的资源,并对请求线程的请求作出允许与否的判断;

Guarded Suspension 示例代码分析

//并发访问的资源对象,与单线程下的实体类并无特别之处
public class Request {
    private final String name;
    public Request(String n){
        name=n;
    }
    public String getName(){
        return name;
    }
    public String toString(){
        return "[request "+name+"]";
    }
}
//实体资源管理类,是实现Guarded Suspension模式的地方
public class RequestQueue {
    private final Queue<Request> queue=new LinkedList<>();
    public synchronized Request getRequest(){//注意这是一个同步方法
        while(queue.peek()==null){//当没有资源时,就阻塞请求
            try{
                wait();
            }catch (InterruptedException e){
                e.printStackTrace();
            }
        }
        return queue.remove();
    }
    public synchronized void putRequest(Request r){
        queue.offer(r);
        notifyAll();//放入一个资源,自然要通知等待该资源的线程
    }
}
//资源的添加者
public class ClientThread extends Thread{
    private final Random random;
    private final RequestQueue queue;
    public ClientThread(RequestQueue requestQueue,String name,long seed){
        super(name);
        this.queue=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()+" requests "+request);
            queue.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 rq,String name,long seed){
        super(name);
        random=new Random(seed);
        requestQueue=rq;
    }
    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 static void main(String[] args){
    RequestQueue requestQueue=new RequestQueue();
    new ClientThread(requestQueue,"Alice",201530L).start();
    new ServerThread(requestQueue,"Bobby",150713L).start();
}

对Guarded Suspension模式的理解

多线程编程,其核心就是对资源的并发访问,所以其要解决的问题就是对临界资源的合理使用:Single Threaded Execution 模式是说通过每次只有一个线程可以访问资源来管理临界资源;Immutable 模式是说保持被访问的资源不会因线程访问而改变以此保证并发;而Guarded Suspension 模式则允许多个线程对实例资源进行访问,但是实例资源需要对资源的分配做出管理;并发访问更多的是指对某一资源的处理是并发的,但是获取资源的过程却必须互斥进行;对核心资源的访问,通常都是互斥进行的,互斥是为了程序合理进行,这也是程序存在的根本的目的;Guarded Suspension模式是说,当资源无法满足请求时就阻塞请求线程,以此保证业务逻辑的正确;就像同时有10辆车从工厂往外运货物,并发就像10辆车同时在公路上运输,而卡车装载的过程却必须一辆辆来。处理就像运输,装载就是请求:并发处理,互斥请求!当工厂没有货物时自然要让卡车等待;但是如果工厂没有做多线程的处理(互斥处理),那么多辆卡车到来时系统就乱套了。这也是多线程代码和单线程代码的区别:要时刻考虑并发访问的情况并做出互斥处理。

猜你喜欢

转载自blog.csdn.net/slx3320612540/article/details/81191657
今日推荐