1.1
並發編程的目的:並發編程是為了讓程序運行得更快,當 並不是啟動更多的線程就能讓程序最大限度地並發執行,受限於死鎖和上下文切換問題。
上下文切換:
CPU通過分配算法循環分配任務,當前任務執行一個時間片後會切換到下一個任務,但是會保存上一個任務的狀態,以便下次切換為這個任務的時候,可以重新加載這個任務,所以任務從保存到加載為一個上下文切換。
所以上下文切換會影響線程的執行速度。
join 的作用
多線程一定比單線程快嗎?
不一定,在測試中並發數量沒超過百萬次的時候,串行比並發速度更快,因為線程有線程的創建和上下文切換的開銷。
如何減少上下文切換?
方法有無鎖並發編程、CAS算法、使用最少線程和使用協程
無鎖並發編程:
多線程競爭鎖時,會引起上下文切換,所以多線程處理數據的時候,可以用一些方法避免使用鎖,如將數據的ID安裝hash算法取模分段,不同線程處理不同段的數據
CAS算法:
java的Atomic包使用CAS算法更新數據,而不需要加鎖
使用最少線程:
避免創建不需要的線程,比如任務很少,但是創建了很多線程來處理,會讓很多線程處理等待狀態
協程
在單線程中實現多任務的調度,並在單線程中維持多個任務的切換。
1.2 死鎖
避免死鎖的幾個方法
避免一個線程獲取多個鎖
避免一個線程在鎖內佔用多個資源,儘量保證每個鎖只佔用一個資源
嘗試使用定時鎖,lock.tryLock()來代替內部鎖機制
對於資料庫鎖,解鎖和加鎖必須連在同一個資料庫中