多線程服務器的體系結構
Architecture for Multithread Servers
- Worker pool
- Thread-per-request
- Thread-per-connection
- Thread-per-object
1. 線程池 Worker pool
1.1 定義
線程池是一組預先實例化的空閒線程,它們隨時可以進行工作。當要執行大量的短任務而不是少量的長任務時,優先於爲每個任務實例化新線程。這樣可以避免產生大量線程的開銷。
1.2 實現
實施會因環境而異,但簡單來說,您需要以下內容:
- 一種創建線程並使它們保持空閒狀態的方法。這可以通過讓每個線程在屏障處等待直到池將其交給工作來實現。(這也可以用互斥鎖完成。)
- 一個用於存儲創建的線程的容器,例如隊列或任何其他可以將線程添加到池中並從中拉出的結構。
- 線程在工作中使用的標準接口或抽象類。這可能是一個抽象類,該類
Task
使用execute()
完成工作然後返回的方法來調用
1.3 線程池工作的具體過程
創建線程池時,它將實例化一定數量的線程以使其可用.
將線程池處理一個任務時
,它將從容器中獲取一個線程(如果容器爲空,則等待一個線程可用),將處理這個任務。
這將導致空閒線程恢復執行,並調用給定的execute()
方法。
執行完成後,線程將自己移回池中以放入容器中以供重用,使自己進入睡眠狀態,直到循環重複。
1.4 優點
每當您需要異步執行某些操作時,創建一個新的線程對象都是很昂貴的。在線程池中,您只需將希望異步執行的任務添加到任務隊列中,線程池就會爲相應任務分配可用線程(如果有)。任務完成後,現在可用的線程將請求另一個任務(假設還有剩餘的任務)。
線程池可以幫助您避免創建或破壞超出實際需要的線程。
1.5 例子
您有一個設施,那裏有12個人在工作。該設施共有3個部分。廚房,洗手間和安全性。如果您不使用線程池技術,那麼它就是這樣工作的:所有12個人都將站在會議室中,如果新客戶來訪並要求任務,那麼您將把人們分成幾組並派他們去做,然後回到會議室。但是,在他們上班之前,有一個準備階段。他們需要穿着正確的制服,配備某些設備,然後步行到該區域,完成工作並返回。因此,每次他們完成工作(線程結束)後,就需要回到會議室,脫下制服,拿出設備並等待下一份工作。這些指的是創建線程上下文,它是操作系統的內存分配和跟蹤信息。
如果使用線程池,那麼在清晨,您將爲廚房分配6個人,爲衛生間分配2個人,爲安全分配4個人。因此,他們每天只會做一次準備。即使廚房裏沒有顧客,那四個人也會閒着閒逛,等待即將來臨的工作。在廚房關閉(應用結束)之前,他們不需要回到會議室。這4個人位於Kitchen應用程序池中,可以快速提供服務。但是,您不能保證他們會整天工作,因爲廚房可能會不時變得閒置。同樣的邏輯也適用於洗手間和安全性。
在第一種情況下,您不會爲任何任務浪費任何線程,但是爲每個任務準備每個線程將花費大量時間。在第二篇文章中,您預先準備了線程,因此您不能保證將所有線程都用於所有任務,但是OS在很大程度上對其進行了優化,因此您可以放心地依賴它。
圖解:
參考:https://softwareengineering.stackexchange.com/questions/173575/what-is-a-thread-pool
2. Thread-per-request
IO線程會爲每個請求創建一個新的工作線程,工作線程在處理請求後會自行銷燬。
3. Thread-per-connection
服務器將線程與每個連接關聯,並在客戶端關閉連接時銷燬。客戶端可能通過連接發出許多請求。
4. Thread-per-object
將線程與每個對象相關聯。 IO線程接收請求並將其排隊以供工作人員使用,但這一次存在每個對象的隊列。
圖解: