併發編程挑戰:死鎖與上下文切換


引言

上下文切換(有時也稱作進程切換或任務切換)是指 CPU 從一個進程或線程切換到另外一個進程或線程。上下文切換會影響多線程執行速度。死鎖是指多個進程或線程循環等待它方佔有的資源而無限期地僵持下去的局面。算法

一、上下文切換

上下文定義

cpu發生進程或者線程切換時,所依賴的數據集合,好比一個函數有外部變量,函數運行時,必須獲取外部變量,這些變量值的集合就是上下文。編程

引起問題

對於CPU密集型任務,多線程處理會發生上下文切換,會影響到執行速度,若是時IO密集型,多線程技術優勢盡顯。多線程

如何減小上下文切換

  • 無鎖併發編程,鎖的獲取與釋放會發生上下文切換,多線程時會影響效率。無鎖併發編程就是將數據分塊,每一個線程處理各自模塊。好比LongAdder中部分代碼。
  • CAS算法,併發編程時經過CAS算法更新數據,而沒必要加鎖。如Java的atomic包下的工具類。
  • 使用最少線程,減小沒必要要的線程建立,自定義線程池。
  • 使用協程,在單線程中維護多任務調度,處理任務間切換,Golang對於協程的使用很強大。

二、死鎖

死鎖定義

死鎖是進程死鎖的簡稱,是由Dijkstra於1965年研究銀行家算法時首先提出來的。 系統發生死鎖現象不只浪費大量的系統資源,甚至致使整個系統崩潰,帶來災難性後果。 死鎖.png併發

產生死鎖緣由

  • 系統資源不足
  • 進程推動順序不當
  • 資源分配不合理

死鎖產生的必要條件

  • 互斥條件:一個資源只能被一個進程或者線程使用。
  • 請求和保持條件:一個進程或者線程,請求資源的時候發生阻塞,對已經獲取的資源保持不放。
  • 不可剝奪條件:進程或者線程以得到的資源,在未使用完成時,不能強行剝奪。
  • 循環等待條件:若干進程或者線程造成一種頭尾相接的循環等待的資源關係。

這四分條件是死鎖產生的必要條件,只要發生死鎖,這些條件必然成立,而只要上述條件之一不知足,就不會發生死鎖。函數

如何避免死鎖

  1. 以肯定的順序得到鎖
  2. 加鎖時限 Lock接口提供了boolean tryLock(long time, TimeUnit unit) throws InterruptedException方法,該方法能夠按照固定時長等待鎖,所以線程能夠在獲取鎖超時之後,主動釋放以前已經得到的全部的鎖。
  3. 死鎖檢測(銀行家算法)

tencent.jpg

相關文章
相關標籤/搜索