併發設計模式34:WorkThread 設計模式
阿新 • • 發佈:2021-06-11
1.WorkThread 設計模式
可以有效避免頻繁建立,銷燬以及OOM問題
2.類比現實
類比車間的工作模式
車間工人,有活大家一起幹,沒活就聊聊天
車間裡工人的數量是確定的
3.程式設計世界對映車間的套路呢
如何實現Worker Thread模式
阻塞佇列做任務池,建立固定數量的執行緒消費阻塞佇列。
這個方案就是執行緒池方案
4.執行緒池方案,解決Thread-Per-Message的問題
虛擬碼
ExecutorService es = Executors .newFixedThreadPool(500); final ServerSocketChannel ssc = ServerSocketChannel.open().bind( new InetSocketAddress(8080)); //處理請求 try { while (true) { // 接收請求 SocketChannel sc = ssc.accept(); // 將請求處理任務提交給執行緒池 es.execute(()->{ try { // 讀Socket ByteBuffer rb = ByteBuffer .allocateDirect(1024); sc.read(rb); //模擬處理請求 Thread.sleep(2000); // 寫Socket ByteBuffer wb = (ByteBuffer)rb.flip(); sc.write(wb); // 關閉Socket sc.close(); }catch(Exception e){ throw new UncheckedIOException(e); } }); } } finally { ssc.close(); es.shutdown(); }
5.建立執行緒池的正確姿勢
java執行緒池可以避免無限制的建立執行緒導致OOM
也可以避免無限制的接受任務導致OOM(執行緒池指定遊街佇列接受任務)
當請求量大於有界佇列容量時,就合理的拒絕請求。同時建立時,要給執行緒賦予一個業務相關的名字
範例
ExecutorService es = new ThreadPoolExecutor( 50, 500, 60L, TimeUnit.SECONDS, //注意要建立有界佇列 new LinkedBlockingQueue(2000), //建議根據業務需求實現ThreadFactory r->{ return new Thread(r, "echo-"+ r.hashCode()); }, //建議根據業務需求實現RejectedExecutionHandler new ThreadPoolExecutor.CallerRunsPolicy());
6.注意事項
提交到相同執行緒池中的任務一定是相互獨立的,最好不要相互依賴
7.總結
Worker-Thread 其實也是一種分工模式
Thread-Pre-Message 類比現實中的委託他人辦理
Worker-Thread 類似車間工人的工作模式
Worker-Thread 能避免執行緒頻繁建立,銷燬,而且可以限制執行緒的最大數量。java語言可以直接使用執行緒池實現WorkerThread模式,執行緒池是一個基礎及優秀的工具類。大廠是不允許使用new Thread()來建立執行緒的,必須用執行緒池。
8.擴充套件
// 只有一個執行緒的執行緒池 ExecutorService pool = Executors.newSingleThreadExecutor();