線程初步理解

線程初步理解

1、線程

  線程會共享進程範圍內的資源,同時,每一個線程也會有各自的程序計數器,棧,以及了局部變量。java

  線程有效下降了程序開發、維護成本,提高了複雜應用程序的性能,讓系統能夠更好地利用計算機資源,提升系統的處理能力,爲用戶界面提供更加靈敏的響應。編程

2、多線程的危險

  1. 安全性問題 :在多個線程不徹底同步的狀況下,多個線程執行的順序是不可預測的,那麼不一樣的執行順序就可能帶來極其糟糕的結果。
  2. 活躍性問題 :活躍性問題關注「某件正確的事情是否最終會發生」,有時候由於線程之間的相互等待,或者單線程的無限循環問題,就會引起活躍性問題。
  3. 性能問題 :線程總會帶來額外的運營開銷,若是這些開銷過於大,會直接影響到系統的性能。

3、線程安全類

  • 定義
      如何定義一個類是線程安全的呢?最核心的問題在於正確性,在代碼中無需進行額外的同步或者協同操做的狀況下,不管有多少個線程使用這個類,不管環境以何種方式調度多線程,這個類總能表現出正確的行爲,咱們就成這個類是線程安全的。安全

  • 無狀態的對象必定是線程安全的
      由於無狀態的線程不會影響到其餘線程的狀態,這個線程中的操做並不會影響到其餘線程的執行,因此無狀態的對象必定是線程安全的。多線程

  • 當一個無狀態的對象增長一個狀態時,若是這個狀態徹底有線程安全的對象來管理,那麼原來這個對象仍然是線程安全的。併發

4、競爭狀態和競爭條件

  • 競爭狀態
      在併發編程中,因爲不恰當的執行時序而致使的結果的錯誤,這種狀況叫作競爭狀態性能

  • 競爭條件
      引起競爭狀態的條件就是競爭狀態的競爭條件atom

  • 原子操做
      原子操做即指某動做要不不完成,要不一次性完成,中間不會被打斷或者干擾線程

  • 競爭條件「先檢查後執行」
      "先檢查後執行"是最多見的一種競爭條件。」先檢查後執行」即先進行檢查某狀態,而後根據這種狀態來決定下面發生的動做,這種方式不具備原子性,那麼這種依賴的狀態就可能在動做發生以前發生變化,最終致使結果的錯誤。總結來講,「先檢查後執行」依賴的是不可靠的狀態條件,由於可能會發生錯誤。對象

5、解決競爭狀態

1.單狀態狀況-使用java.util.concurrent.atomic下的原子變量

  • 這些原子變量的增長減小等運算均可以保持原子性,那麼就會保證某個狀態是線程安全的。

2.複合狀態的狀況

  • 若是再使用第一種方法,雖然多個變量各自能夠保持線程安全,可是多個變量之間的協同不是原子的操做。例如a變量和b變量有某種聯繫,a和b須要作同步的修改,那麼修改的操做也必須是原子操做。於是第一種方法就失效了。
  • Java提供了一種內置鎖的機制:同步代碼塊(Synchronized Block),這種機制能夠保證某個過程是原子操做,從而保證了線程安全。

6、Java內置鎖

1.同步代碼塊(Synchronized Block)

  1. Java的同步代碼塊有兩部分組成,一部分是由鎖保護的代碼塊,另外一部分是鎖的對象。
    • 以synchronized修飾的方法就是由鎖保護的代碼塊。
    • 這個方法所在的對象就是這個鎖,靜態方法的話,方法所在的class就是鎖。
  2. 重入
    • Java內置鎖是能夠重入的,即同一線程能夠對本身持有的鎖進行反覆的進入。實現方法是:鎖是有計數器和持有者這兩個變量,計數器默認爲0,持有者爲空,當有人訪問鎖時候,JVM會自增計數器,而且將持有者設置爲鎖的對象,只有當同一個線程再次訪問這個鎖的時候,線程還能夠得到這個鎖,而且計數器增長;退出後,釋放鎖,計數器減小。
  3. 同步代碼塊可能來性能問題,由於多個線程只能有一個來執行被鎖定的方法,其餘處於等待的過程,會出現性能缺失。
相關文章
相關標籤/搜索