執行緒之旅--Guarded Suspension Pattern
在家換衣服時,突然門鈴響了,原來郵遞員送快遞了。因為衣服不能換了一半就出去,所以對郵遞員將,請您稍等。在把門開啟,說“讓您久等了”,Guarded Suspension Pattern 就是適合這種情況的
下面我們用個簡單的例子來進行說明(範例由5個檔案組成): 大家在要注意為什麼要加synchronized ,它想保護的究竟是什麼,為什麼要wait,為什麼put後要nitifyAll();
Main.java--呼叫類
public class Main {
public static void main(String[] args) {
RequestQueue requestQueue = new RequestQueue();
new ClientThread(requestQueue, "郵遞員", 3141592L).start();
new ServerThread(requestQueue, "主人", 6535897L).start();
}
}
Request.java--請求類
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.java--請求佇列
import java.util.LinkedList;
public class RequestQueue {
private final LinkedList queue = new LinkedList();
public synchronized Request getRequest() {
while (queue.size() <= 0) {
try {
wait();
} catch (InterruptedException e) {
}
}
return (Request)queue.removeFirst();
}
public synchronized void putRequest(Request request) {
queue.addLast(request);
notifyAll();
}
}
ClientThread.java--送出請求類
import java.util.Random;
public class ClientThread extends Thread {
private Random random;
private 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() + " 送出請求 " + request);
requestQueue.putRequest(request);
try {
Thread.sleep(random.nextInt(1000));
} catch (InterruptedException e) {
}
}
}
}
ServerThread.java--接受請求類
import java.util.Random;
public class ServerThread extends Thread {
private Random random;
private 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() + " 處理 " + request);
try {
Thread.sleep(random.nextInt(1000));
} catch (InterruptedException e) {
}
}
}
}