執行緒池管理(1)-為什麼需要執行緒池

方丈發表於2019-05-04

摘要

為什麼需要執行緒池呢,沒想明白這個問題,看再多執行緒池的原始碼都沒有用,先要知道執行緒池技術解決了什麼問題,才能看的懂原始碼,因為所有的程式碼都是為了解決實際的工程問題。

問題

拋幾個問題,看看你是否知道,不知道的話,可能你對執行緒池的理解還不夠深入,還是一知半解。那麼本文會對你有用,請繼續看下去

  • 執行緒池的執行緒數可以為1嗎?
  • 執行緒數為1的執行緒池有存在的必要嗎
  • 2個有5個核心執行緒的執行緒池和1個有10個核心執行緒的執行緒池有什麼區別
  • 一個應用中如何管理執行緒池
  • 執行緒池池化技術和訊息佇列有什麼區別

執行緒池原理

在大學裡我們學習c語言時,一個main函式寫到底,就可以交作業了。剛開始工作時,mvc一路controller -> service -> dao就OK了。但是工作中寫程式碼是要解決實際問題的。你啪啪啪寫完了程式碼,使用者發現你這個介面響應太慢了,怎麼辦?

在這裡插入圖片描述
使用者提交任務到程式執行完成,大致的過程如上圖,提交一個task,然後有個執行緒去執行。 所以要提高​程式執行的效率可以從兩個方面來考慮

  1. 非同步,先響應,返回中間結果,然後非同步處理,將結果返回
  2. 併發,多個執行緒來執行。

本篇說的執行緒池主要就是從1的維度來提高程式執行的效率

生產者消費者模式

有一定工作經驗的朋友對訊息佇列的削峰填谷,系統解耦肯定不陌生。那麼執行緒池,算不算削峰填谷呢? 非同步化後,相當於把所有的task放在了佇列中。也就是生產者 -> 容器 -> 消費者。如下圖

在這裡插入圖片描述
從圖可以看出,執行緒池技術使系統複雜了,也提供了更多的靈活性。通過佇列的形式,我們將任務的執行拆分成了生產者,消費者模式。每一步只用關心自己的事情。如果我們的任務很複雜,我們可以將任務拆分成不同的步驟,每一步驟可以使用不同的執行緒池來解決,以此來提高效率。

可管理性

看上去通過執行緒池完美解決了我們的問題,那麼需要付出什麼代價呢?cpu的資源是有限的,執行緒的建立也需要代價,我們一個java應用程式的資源是畢竟是有限的。我們不可能在應用中無限的建立執行緒池。所以我們需要管理執行緒池。

通常,對於簡單的應用,我們使用一個單例執行緒池即可,讓應用中的所有task都使用同一個執行緒池,防止一些初級程式設計師在應用中隨意建立執行緒池,導致執行緒資源吃緊,執行緒佔用過多的資源。

當應用中task比較複雜的時候,我們就需要使用分治的思想,對執行緒池進行隔離。 比如有些是cpu密集型的,有些是IO密集型的;任務的重要程度也有輕重之分;任務的執行時間也有不同。我們需要對為這些任務建立不同的執行緒池,以此來提高效率。

總結

執行緒池是一種非同步化技術,通過預先建立執行緒/非同步處理來提高響應速度。同時通過統一調配執行緒資源,可以降低執行緒的重複建立問題,提高執行緒的利用率,中心化管理有利於對資源的有效控制,防止濫用。

關注【方丈的寺院】,與方丈一起開始技術修行之路

在這裡插入圖片描述

相關文章