Thread-Per-Message 模式


如 果您現在設計一個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("資料送出")