Work Thread模式和Thread-Per-Message模式相似,Thread-Per-Message每次都建立一個新的線程處理請求,而Work Thread模式預先會建立一個線程池(Thread Pool),每次從線程池中取出線程處理請求。dom
Request請求類:性能
public class Request { private final String name; private final int number; private static final Random random = new Random(); public Request(String name, int number) { this.name = name; this.number = number; } public void execute() { System.out.println(Thread.currentThread().getName() + " executes " + this); try { Thread.sleep(random.nextInt(1000)); } catch (InterruptedException e) { } } public String toString() { return "[ Request from " + name + " No." + number + " ]"; } }
Client線程類:
Client線程類用來送出請求:this
public class ClientThread extends Thread { private final Channel channel; private static final Random random = new Random(); public ClientThread(String name, Channel channel) { super(name); this.channel = channel; } public void run() { try { for (int i = 0; true; i++) { Request request = new Request(getName(), i); channel.putRequest(request); Thread.sleep(random.nextInt(1000)); } } catch (InterruptedException e) { } } }
Worker線程類:
WorkerThread類表示工人線程,工人線程能夠執行如下動做:spa
public class WorkerThread extends Thread { private final Channel channel; public WorkerThread(String name, Channel channel) { super(name); this.channel = channel; } public void run() { while (true) { Request request = channel.takeRequest(); request.execute(); } } }
Channel類:線程
/** *Channel類可用來接受、傳送工做請求,並保存工人線程。 */ public class Channel { private static final int MAX_REQUEST = 100; // 最大請求數 private final Request[] requestQueue; // 請求隊列 private int tail; private int head; private int count; private final WorkerThread[] threadPool; public Channel(int threads) { this.requestQueue = new Request[MAX_REQUEST]; this.head = 0; this.tail = 0; this.count = 0; threadPool = new WorkerThread[threads]; for (int i = 0; i < threadPool.length; i++) { threadPool[i] = new WorkerThread("Worker-" + i, this); } } public void startWorkers() { for (int i = 0; i < threadPool.length; i++) { threadPool[i].start(); } } public synchronized void putRequest(Request request) { while (count >= requestQueue.length) { try { wait(); } catch (InterruptedException e) { } } requestQueue[tail] = request; tail = (tail + 1) % requestQueue.length; count++; notifyAll(); } public synchronized Request takeRequest() { while (count <= 0) { try { wait(); } catch (InterruptedException e) { } } Request request = requestQueue[head]; head = (head + 1) % requestQueue.length; count--; notifyAll(); return request; } }
執行:code
public class Main { public static void main(String[] args) { Channel channel = new Channel(5); channel.startWorkers(); new ClientThread("Alice", channel).start(); new ClientThread("Bobby", channel).start(); new ClientThread("Chris", channel).start(); } }
Work Thread模式的角色以下:隊列
Client參與者會建立請求(Request),而後傳送給Channel參與者。資源
Channel參與者保存Request請求隊列,同時會預建立Worker線程。rem
Worker參與者會從Channel獲取Request。get
Worker參與者會從Channel獲取Request。
注:啓動線程是一項繁重的工做,Worker Thread模式預先建立一批線程,能夠重複使用線程,達到資源再利用、提高性能的目的。