Guarded Suspension 模式

Guarded Suspension 模式

Guarded Suspension 模式通过让线程等待来保证示例的安全性。

示例程序

类的一览表

名字 说明
Request 表示一个请求的类
RequestQueue 依次存放请求的类
ClientThread 发送请求的类
ServerThread 接收请求的类
Main 测试程序行为的类

示例程序的时序图

时序图

Request类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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 + " ]";
}
}

RequestQueue类

RequestQueue类用于依次存放请求。该类中定义了getRequest和putRequest两个方法。

getRequest方法

getRequest方法会去除最先存放在RequestQueue中的一个请求,作为其返回值。如果一个请求都没有,那就一直等待,知道其他某个线程执行putRequest。

putRequest方法

putR方法用于添加一个请求。当线程想要向RequestQueue添加Request实例,可调用该方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class RequestQueue {
private final Queue<Request> queue = new LinkedList<>();

public synchronized Request getRequest() {
while (null == queue.peek()) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return queue.remove();
}

public synchronized void putRequest(Request request) {
queue.offer(request);
notifyAll();
}
}

ClientThread类

ClientThread类用于表示发送请求的线程。ClientThread持有RequestQueue的实例,并连续调用该实例的putRequest,放入请求。请求的名称依次为“No.0”、“No.1”……
为了错开发送请求的时间点,这里使用Random类随机生成了0-1000之间的数,来作为sleep的时间。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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 index = 0; index < 10000; index++) {
Request request = new Request("No." + index);
System.out.println(Thread.currentThread().getName() + " requests " + request);
requestQueue.putRequest(request);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

ServerThread类

ServerThread用于表示接受请求的线程。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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 index = 0;index < 10000; index++) {
Request request = requestQueue.getRequest();
System.out.println(Thread.currentThread().getName() + " handles " + request);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

Main类

1
2
3
4
5
6
7
public class Main {
public static void main(String[] args) {
RequestQueue requestQueue = new RequestQueue();
new ClientThread(requestQueue, "Alice", 3141592L).start();
new ServerThread(requestQueue, "Bobby", 6535897L).start();
}
}

运行结果

执行结果

0%