一、简介
Guarded Suspension Design Pattern(保持性暂挂模式)意为保护暂停,其核心思想是仅当服务进程准备好时,才提供服务。当线程在访问某个对象时,发现条件不满足,就暂时挂起等待条件满足时再次访问。
二、Guarded Suspension Design Pattern 模式的结构
Guarded Suspension模式的主要成员有:Request、RequestQueue、ClientThread、ServerThread
①.Request:表示客户端请求
②.RequestQueue:用于保存客户端请求队列
③.ClientThread:客户端进程
④.ServerThread:服务器进程
三、适用场景
多线程编程中,往往将一个任务分解为不同的部分,将其交由不同的线程来执行,这些线程相互协作的时候,会出现一个线程等待另一个线程一定操作过后才能进行的情景,这个时候就需要这个线程退出执行。
四、场景模拟
例如你在家做菜,到了关键时刻不能抽开身去干其他事情,这个时候有一个快递叫你去签收一下。但是这个时候你又不能离开厨房,你只好叫快递小哥等一下,等你把菜做好(也就是准备好去签收快递),你才去签收这个快递。
五、代码实例
①.Request 客户端请求类
package chapter2.guardedsuspension;
/**
* @author czd
*/
public class Request {
private String value;
public Request(String value){
this.value = value;
}
public String getValue() {
return value;
}
}
②.RequestQueue 保存客户端请求队列类
package chapter2.guardedsuspension;
import java.util.LinkedList;
/**
* @author czd
*/
public class RequestQueue {
private LinkedList<Request> queue = new LinkedList<Request>();
public Request getRequest(){
synchronized (queue){
while (queue.size() <= 0){
try {
queue.wait();
}catch (Exception e){
e.printStackTrace();
return null;
}
}
return queue.removeFirst();
}
}
public void putRequest(Request request){
synchronized (queue){
queue.addLast(request);
queue.notifyAll();
}
}
}
③.ClientThread 客户端进程类
package chapter2.guardedsuspension;
/**
* @author czd
*/
public class ClientThread extends Thread {
private RequestQueue queue ;
private String sendValue;
public ClientThread(RequestQueue requestQueue , String sendValue){
this.queue = requestQueue;
this.sendValue = sendValue;
}
@Override
public void run() {
for (int i = 0; i < 10; i++){
System.out.println("Client >>>>> request >>>>>" + sendValue);
queue.putRequest(new Request(sendValue));
try {
Thread.sleep(100);
}catch (Exception e){
e.printStackTrace();
}
}
}
}
④.ServerThread 服务端进程类
package chapter2.guardedsuspension;
/**
* @author czd
*/
public class ServerThread extends Thread {
private RequestQueue queue;
private volatile boolean flag = true;
public ServerThread(RequestQueue queue){
this.queue = queue;
}
@Override
public void run() {
while (flag){
Request request = queue.getRequest();
if (request == null){
System.out.println("request 是空的");
continue;
}
System.out.println("Server>>>>>>" + request.getValue());
try {
Thread.sleep(100);
}catch (Exception e){
e.printStackTrace();
return;
}
}
}
public void close(){
this.flag = false;
this.interrupt();
}
}
⑤.SuspensionTest 测试类
package chapter2.guardedsuspension;
/**
* @author czd
*/
public class SuspensionTest {
public static void main(String[] args) {
RequestQueue queue = new RequestQueue();
new ClientThread(queue , "快递").start();
ServerThread serverThread = new ServerThread(queue);
serverThread.start();
}
}
输出结果
六、需要关注的问题
①.内存可见性和锁泄露
②.线程被过早唤醒
③.嵌套监视器锁死
④.可能增加JVM垃圾回收的负担