Worker Thread 模式

来源:互联网 发布:软件制作大师 编辑:程序博客网 时间:2024/06/10 14:46
每個執行緒處理一個請求,每次執行緒執行完請求後,再次嘗試取得下一個請求並執行,這是Worker Thread的基本概念,對於一些需要冗長計算或要在背景執行的請求,可以採用Worker Thread。

在 
Thread-Per-Message 模式 中,其實已經有點Worker Thread的概念,在Service物件接收到資料後,以匿名方式建立執行緒來處理資料,那個建立的執行緒就是Worker Thread,只不用過就丟了。

Worker Thread可以應用在不同的場合,例如在 
Guarded Suspension 模式 的範例,是使用一個執行緒來處理請求佇列中的請求,如果請求不斷來到,且請求中可能有冗長的處理,則請求佇列中的請求可能會來不及消化。

您可以為請求佇列中的每個請求配給一個執行緒來處理,不過實際上,只要建立足夠多的執行緒即可,在以下的範例中,可以指定請求佇列預先建立的執行緒數量,每個執行緒會取出一個請求來執行。
import java.util.*;interface Request {    void execute();}class Worker implements Runnable {    private RequestQueue queue;    Worker(RequestQueue queue) {        this.queue = queue;    }    public void run() {        while(true) {            queue.get().execute();        }    }}class RequestQueue {    private LinkedList<Request> requests;        RequestQueue(int workers) {        requests = new LinkedList<Request>();        for(int i = 0; i < workers; i++) {            (new Thread(new Worker(this))).start();        }    }    synchronized Request get() {        while(requests.size() == 0) {            try {                wait();            }            catch(InterruptedException e) {                e.printStackTrace();            }        }        return requests.removeFirst();    }    synchronized void put(Request request) {        requests.addLast(request);        notifyAll();    }} // 模擬 Client 置入請求class Client implements Runnable {    private RequestQueue queue;    Client(RequestQueue queue) {        this.queue = queue;    }    public void run() {        while(true) {            Request request = new Request() {                public void execute() {                   System.out.println("執行客戶請求...XD");                   try {                       Thread.sleep((int) (Math.random() * 3000));                    }                   catch(InterruptedException e) {                       e.printStackTrace();                   }                }            };            queue.put(request);            try {                Thread.sleep((int) (Math.random() * 3000));             }            catch(InterruptedException e) {                e.printStackTrace();            }        }    }}public class Main {    public static void main(String[] args) {        RequestQueue queue = new RequestQueue(5);        for(int i = 0; i < 5; i++) {            (new Thread(new Client(queue))).start();        }        }}

在這個範例中,
 Worker Thread有請求來了就作,如果沒有請求,則所有的Worker Thread就等待,直到有新的工作進來而通知它們,取得請 求的WorkerThread要作的工作,就直接定義在execute()中。 

以順序圖來表示這個範例:

若使用Python來示範的:
import threadingimport timeimport randomclass Worker(threading.Thread):    def __init__(self, queue):        threading.Thread.__init__(self)        self.queue = queue        def run(self):        while True:            self.queue.get()()        class RequestQueue:    def __init__(self, workers):        self.requests = []        self.condition = threading.Condition()        for i in range(workers):            Worker(self).start()    def get(self):        self.condition.acquire()        while not self.requests:            self.condition.wait()        request = self.requests.pop(0)        self.condition.release()        return request       def put(self, request):        self.condition.acquire()        self.requests.append(request)        self.condition.notify()        self.condition.release()class Client(threading.Thread):    def __init__(self, queue):        threading.Thread.__init__(self)        self.queue = queue            def run(self):        while True:            second = int(random.random() * 3) # 隨機模擬請求的執行時間            request = lambda: print("執行客戶請求...XD"); time.sleep(second)            self.queue.put(request)            time.sleep(int(random.random() * 3))            queue = RequestQueue(5)for i in range(5):    Client(queue).start()        while True:    try:        time.sleep(1)    except KeyboardInterrupt:        exit()
原创粉丝点击