Guared Suspension
设计模式
针对
Guared Suspension设计模式,我们先结合一下现实生活中的例子来认识一下它。当你正在家换衣服时,门铃突然响了,原来是邮递员来送快递了,这时,因为正在换衣服出不去,所以只能喊道,“请稍等一下”,让快递员在门口稍等一会儿,换好衣服后,才说着“让你久等了”并打开门
...
Guared Suspension
模式,
Guared
是被守护,被保卫,被保护的意思,
Suspension
则是暂停的意思。如果执行现在的处理会造成问题,就让执行处理的线程进行等待
----
这就是
Guared Suspension
模式。
Guared Suspension
模式通过让线程等待来保证实例的安全性,这正如你让快递员在门口等待,以保护个人隐私一样。
我们来看一下示例程序,先介绍一相关用到的类:
Request类表示一个请求的类,
RequestQueue
类表示依次存放请求的类,
ClientThread
表示发送请求的类,
ServerThread
表示接收请求的类。
Request
类用于表示请求,虽说是请求,但由于只是用于表示
ClientThread
传递给
ServerThread
的实例,所以不提供什么特殊处理,只有一个
Name
属性
public class Request {
private final String name;
public Request(String name) {
this.name = name;
}
public String getName() {
return name;
}
public String toString() {
return "Request [name=" + name + "]";
}
}
RequestQueue
类用于依次存放请求,定义了
getRequest
和
putRequest
两个方法。
getRequest
方法会取出最先存放在在
RequestQueue
中的一个请求,作为其返回值,如果一个请求都没有,那就一直等待,直到其他某个线程执行
putRequest.
putRequest
方法用于添加一个请求,当线程想要向
RequestQueue
中添加实例时可以调用该方法。
总的来说,
RequestQueue通过
putRequest
放入
Request实例,并按放入顺序使用
getRequest取出
Request实例,这种结构其实就是队列。import java.util.LinkedList;
import java.util.Queue;
import com.Guared.pojo.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) {
e.printStackTrace();
}
}
return queue.remove();
}
public synchronized void putRequest(Request request) {
queue.offer(request);
notifyAll();
}
}
ClientThread
类表示发送请求的线程,
ClientThread
持有
RequestQueue
的实例
(requestQueue )
,并连续调用该实例
putRequest
,放入请求,请求的名称依次为“
No.0
”
,
“
No.1
”
,
“
No.2
”
.....
为了错开发送请求
(
执行
putRequest)
的时间点。这里使用随机数
0-1000
作为睡眠的时间。
import java.util.Random;
import com.Guared.pojo.Request;
import com.Guared.queue.RequestQueue;
public class ClientThread extends Thread{
private final Random random;
private final 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()+"requests "+ request);
requestQueue.putRequest(request);
try {
Thread.sleep(random.nextInt(1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
ServerThread
类表示接收请求的线程,也持有
RequestQueue
的实例
(requestQueue )
。
ServerThread
使用
getRequest
方法来接收请求。与
ClientThread
一样,使用随机数
0-1000
作为睡眠的时间。
import java.util.Random;
import com.Guared.pojo.Request;
import com.Guared.queue.RequestQueue;
public class ServerThread extends Thread{
private final Random random;
private final RequestQueue requestQueue;
public ServerThread(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 = requestQueue.getRequest();
System.out.println(Thread.currentThread().getName()+"handles"+ request);
try {
Thread.sleep(random.nextInt(1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Main
类运行代码
import com.Guared.queue.RequestQueue;
import com.Guared.thread.ClientThread;
import com.Guared.thread.ServerThread;
public class Main {
public static void main(String[] args) {
RequestQueue requestQueue = new RequestQueue();
new ClientThread(requestQueue, "jack", 3141592L).start();
new ServerThread(requestQueue, "tom", 6535877L).start();
}
}
结果能看出,
jack会一直发送请求,而
tom
则会不断地处理请求。

这就是我们介绍的
Guared Suspension模式
,
在该模式中,线程是否等待取决于守护条件,其实
Guared Suspension
模式是在
Single Threaded Execution
模式的基础上附加了条件而形成的,也就是说
Guared Suspension
模式是类似于“附加条件的
synchronized
”这样的模式。
更多技术资讯可关注:gzitcast