如果您現在設計一個Service元件,可以接受客戶端的資料並交給一個Helper元件處理,假設資料處理很複雜,也就是Helper處理會需要一段時間,如果您這麼設計:
class Helper { void process(int data) { System.out.println("開始處理 " + data); try { Thread.sleep(3000); // 處理過程很費時 } catch(InterruptedException e) { e.printStackTrace(); } System.out.println("處理完成"); } } class Service { private Helper helper = new Helper(); void accept(int data) { helper.process(data); } } public class Main { // 客戶端角色 public static void main(String[] args) { Service service = new Service(); for(int i = 0; i < 10; i++) { System.out.println("傳送資料"); service.accept(i); System.out.println("資料送出"); } } }
那麼客戶端每次都必須等Service元件處理完畢後,才可以進行下一次資料傳送,也就是Service對客戶端的回應性會很差。
您可以改用這樣的設計:
class Helper { void process(int data) { System.out.println("開始處理 " + data); try { Thread.sleep(3000); // 處理過程很費時 } catch(InterruptedException e) { e.printStackTrace(); } System.out.println("處理完成"); } } class Service { private Helper helper = new Helper(); void accept(final int data) { new Thread() {
public void run() {
helper.process(data);
}
}.start(); } } public class Main { public static void main(String[] args) { Service service = new Service(); for(int i = 0; i < 10; i++) { System.out.println("傳送資料"); service.accept(i); System.out.println("資料送出"); } } }
Service對於每個資料接收之後,馬上使用一個執行緒來處理,因此accept()方法會很快的返回,Service對於客戶端可以有很高的回應性。
以UML順序圖來表示以上範例的話:
Thread-Per-Message模式可應用在Service需要有高回應性的場合。服務端對每個請求使用一個執行緒來處理(從這些執行緒角度看,它們是 Worker
Thread),如果服務端在乎建立新執行緒的負擔,則可以考慮結合使用Thread pool 模式。這個模式常用於多人網路連線程式,伺服端接受連線後,使用一個執行緒來處理該次連線,伺服端可馬上傾聽下一個客戶端連線。
使用Python來實現以上範例的話:
import _thread import time class Helper: def process(self, data): print("開始處理 %d" % data) time.sleep(3) # 處理過程很費時 print("處理完成") class Service: def __init__(self): self.helper = Helper() def accept(self, data): _thread.start_new_thread(lambda: self.helper.process(data), ()) service = Service() for i in range(10): print("傳送資料") service.accept(i) print("資料送出")