前一陣子太忙了,最近會開始恢復穩定的更新。
之前聽前輩說在多線程這塊,自己的理論知識還不是很紮實,現在開始把這一塊補起來。
以下是本書第一章的讀書筆記
前言
併發編程的目的是讓程序跑的更快,但並不是啓動更多的線程,這個程序就跑的更快。有以下幾種挑戰。
挑戰及方案
上下文切換
單核CPU上執行多線程任務,通過給每個線程分配CPU時間片的方式來實現這個機制。時間片是CPU分配給每個線程運行的時間,時間片非常短,CPU通過不斷的切換線程執行,給我們人類留下的印象就是多個線程在同時執行。
由於線程有創建和上下文切換的開銷,當整個程序內部操作數不高的情況下,併發執行可能比串行執行來的慢。
儘可能降低上下文切換的次數,有助於提高併發效率。
無鎖併發編程。書中提到多線程競爭鎖時會發生上下文切換,所以竟可能避免使用鎖書中指的應該是爲了競爭鎖而觸發的搶佔式上下文切換,因爲日常多線程運行也需要上下文切換,可以通過不同線程處理不同分段的數據來降低。
CAS算法。Java中的Atomic包使用CAS算法來更新數據,不需要加鎖
CAS算法目前還不是很瞭解使用最少線程。
協程。協程,又稱微線程,纖程。英文名Coroutine。指的是在單線程裏面實現多任務的調度
之前在Python和Go裏面聽過這個概念,不過還沒做具體瞭解。
死鎖
併發編程中的另一挑戰是死鎖,會造成系統功能不可用。死鎖是指兩個或兩個以上的進程或者線程在執行過程中,由於競爭資源或者由於彼此通信而造成的一種阻塞的現象。
避免死鎖的常見方法:
避免一個線程同時獲取多個鎖。
儘可能保證一個鎖內只佔有一個資源。
嘗試使用定時鎖。
資源限制的挑戰
比如說帶寬只有2Mb/s,你下載速度是1Mb/s,開10個線程速度也不會變成10Mb/s。書中提到在併發編程時需要考慮到資源上的限制。如果受制於資源,比如數據庫連接,你每次用完都新建線程來做連接,整體的創建開銷還是比較大的,整體程序的速度肯定會慢下來。
解決的方法有以下幾點:
對於硬件資源的限制,可以使用集羣來跑。
對於軟件資源上的限制,可以複用資源,比如複用數據庫連接。
根據資源的限制,靈活的去調整併發度。