Guarded Suspension
Guarded Suspension模式介绍
如果执行现在的处理会造成问题,就让执行的线程进行等待,Guarded Suspension 模式是通过让线程等待来保护实例的安全性,即守护-挂起模式;
Guarded Suspension 模式的使用场景
- 多线程环境下多个线程访问相同实例资源,从实例资源中获得资源并处理;
- 实例资源需要管理自身拥有的资源,并对请求线程的请求作出允许与否的判断;
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辆车同时在公路上运输,而卡车装载的过程却必须一辆辆来。处理就像运输,装载就是请求:并发处理,互斥请求!当工厂没有货物时自然要让卡车等待;但是如果工厂没有做多线程的处理(互斥处理),那么多辆卡车到来时系统就乱套了。这也是多线程代码和单线程代码的区别:要时刻考虑并发访问的情况并做出互斥处理。