java多線程之Guarded Suspension模式

Guarded Suspension模式(等我準備好哦)

Single Threaded Execution模式中,只要有一個線程進入臨界區,其他線程就無法進入,只能等待。而在Guarded Suspension模式中,線程是否等待取決於守護條件。Guarded Suspension模式是在Single Threaded Execution模式的基礎上附加了條件而形成的。

 

如下一段代碼實例:

 

 

request用於表示請求,表示ClientThread傳遞給ServerThread的實例

public class Request {

private final String name;

 

public Request(String name) {

super();

this.name = name;

}

 

public String getName() {

return name;

}

public String toString(){

return "[Request"+ name+"]";

}

}

RequestQueue類用於依次存放請求,類中定義了getRequest方法和putRequest方法

getRequest方法會取出最先存放在requestQueue中的一個請求,作爲其返回值。如果一個請求都沒有,那麼就一直等待,直到其他線程執行putRequest

putRequest方法用於添加一個請求。當線程想要向RequestQueue中添加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) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

return queue.remove();

}

public synchronized void putRequest(Request request){

queue.offer(request);

notifyAll();

}

}

 

CientThread 類用於表示發送請求的線程。ClientThread持有RequestQueue的實例,並連續調用該實例的putRequest,放入請求,請求的名稱依次爲NO1,NO2.....

爲了錯開發送請求的時間點,使用random隨機生成了01000之間的數,來作爲sleep的時間(以毫秒爲單位)

public class ClientThread extends Thread{

private final Random random;

private final RequestQueue requestQueue;

public ClientThread(RequestQueue requestQueue,String name,long seed){

this.requestQueue = requestQueue;

this.random = new Random(seed);

}

public void run(){

for (int i = 0; i < 1000; i++) {

Request request = new Request("No."+i);

System.out.println(Thread.currentThread().getName()+"request:"+request);

requestQueue.putRequest(request);

try {

Thread.sleep(random.nextInt(1000));

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

}

}

 

ServerThread類用於表示接收請求的線程。該類持有RequestQueue的實例 (requestQueue.

ServerThread使用getRequest方法接收請求

 

public class ServerThread  extends Thread{

private final Random random;

private final RequestQueue requestQueue;

public ServerThread(RequestQueue requestQueue,String name,long seed){

this.requestQueue = requestQueue;

this.random = new Random(seed);

}

public void run(){

for (int i = 0; i < 1000; i++) {

Request request = requestQueue.getRequest();

System.out.println(Thread.currentThread().getName()+"handles:"+request);

try {

Thread.sleep(random.nextInt(1000));

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

}

}

 

Main類會首先創建RequestQueue的實例(requestQueue,然後分別創建名爲Alice的實例ClientThread和名爲Boddy的實例ServerThread,並將requestQueue傳給這兩個實例,最後執行start.

public class Main {

public static void main(String[] args) {

RequestQueue requestQueue = new RequestQueue();

new ClientThread(requestQueue, "Alice", 3141592L).start();;

new ClientThread(requestQueue, "Bobby", 6535897L).start();;

}

}

 

 

GuardedObject 角色是一個持有被守護的方法的類.當線程執行guardedMethod方法時,如果條件成立,則可以立即執行,當守護條件不成立,則進行等待。

 

三大特徵:

存在循環

存在條件檢查

因爲某種原因而等待

 

guarded supension :被守護而暫停執行的含義

guarded wait:被守護而等待

 

採用LinkedBlockingQueue時,實例程序中的RequestQueue可以被簡化。

take方法用於取出隊首的元素(將隊頭元素出隊,如果隊列空了,一直阻塞,直到隊列不爲空或者線程被中斷),put方法用於向隊列末尾添加元素(在隊尾插入一個元素,如果隊列滿了,一直阻塞,直到隊列不滿了或者線程被中斷)。這兩個方法都進行了封裝。因爲這兩個方法已經考慮了互斥的方法,所以無需聲明爲synchroized方法。

public class RequestQueue {

private final BlockingQueue<Request> queue = new LinkedBlockingQueue<Request>();

public Request getRequest(){

Request req = null;

try {

req = queue.take();

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}//取出隊首元素

return req;

}

public void putRequest(Request request){

try {

queue.put(request);//向隊列末尾添加元素

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

}

LinkedListLinkedBlockingQueue的比較

 

 

對於Guarded Supension模式的總結:

該模式存在一個持有狀態的對象,只有在這個對象的狀態滿足條件的情況下,纔會允許現在執行目標處理。所以,我們先將這個對象的滿足條件作爲它的“守護條件”,然後,在執行這個目標處理之前,檢查守護條件是否成立,只有當守護條件成立時,線程纔會執行目標處理,而當守護條件不成立時,線程就會一直等到成立爲止,使用while條件嵌套檢查條件,wait()執行等待,使用notifyAll()方法進行通知。這就是Guarded Suspension模式。

發佈了24 篇原創文章 · 獲贊 4 · 訪問量 8759
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章