1. 程式人生 > >Java高效並發

Java高效並發

出現 native http ima tile 可能 evel ssi 決定

一段時間沒有回顧多線程相關知識了,雖然工作中會用到一些多線程的內容,但都偏向於基礎,今天重讀多線程相關內容,發現有些東西還是需要註意下。這些一般是面試高頻問題奧。

了解並發的內幕是一個高級程序員不可缺少的課程

Java內存模型

註意,Java內存模型(JMM)和JVM運行時數據區不是同一個概念,還有一個概念是Java對象模型下次可以單獨拿出來說。

  • JMM都是圍繞著原子性,可見性,有序性來講的
  • JMM定義了JVM如何與計算機的內存進行交互

線程對變量的所有操作都需要在工作內存中完成,不可直接操作主內存。
技術分享圖片

內存間的交互操作:
Lock,Unlock 主內存
Read,Write 主內存
Load,Store 工作內存的變量

Use,Assign 工作內存的變量

更多關於JMM的信息查看,多線程之Java內存模型

Volatile

Volatile可以說是Java虛擬機內提供的最輕量級同步機制,其只保證,可見性與有序性,不保證原子性。

可見性:當一條線程修改了這個變量的值,新值對於其他線程來說是可以立刻得知的,另外兩個可以實現可見性的關鍵字:Synchronizedfinal

有序性:如果再本線程內觀察,所有的操作都是有序的,如果再一個線程中觀察另外一個線程,那麽所有的操作都是無序的。

Java與線程

並發不一定依賴多線程,如PHP中常見的多進程並發。Java的Thread類所有關鍵方法都是聲明為Native的,所以Java並沒有自己實現線程。

實現線程的三種方式:使用內核線程實現,使用用戶線程實現,和使用用戶線程加更加輕量級進程實現。

  1. 內核線程實現(KLT,Kernel-Level Thread)。程序一般不會直接使用內核線程,而是使用內核線程的一種高級接口,輕量級進程(LWP,Light Weight Process,LWP),先有內核線程,才能有輕量級進程。

缺點:各種線程操作,如創建,析構,及同步需要進行系統調用,而系統調用的代價比較高,需要在用戶態和內核態中來回切換。消耗內核資源,一個系統支持輕量級的進程數量是有限制的。

  1. 用戶線程實現,廣義上說,一個線程只要不是內核線程,那就可以任務是用戶線程。用戶線程完全在用戶態完成,不用內核的幫助,可以支持更大的線程數量。

缺點:沒有內核支持,各種操作都比較復雜。現在基本棄用了。

  1. 用戶線程 + 輕量級進程,綜合兩者的有點,用戶進程與輕量級進程數量比是不定的。

線程調度

協同式調度:好處是實現簡單,切換操作對線程自己是可知的,沒有線程同步的問題,線程把自己的事情幹完之後才進行線程切換。

缺點:如果程序編寫不穩定,那麽系統不可控制。一個進程堅持不讓出CPU執行實現,就會導致系統崩潰。

搶占式調度(Java默認調度):每個線程由系統來分配執行和弦,線程的切換不由線程來決定,當一個進程出現問題,系統可以殺掉這個進程。

註意:並不是線程的優先級越高,線程就一定會優先執行,只是說優先級高的線程更可能被選擇到。

Java線程狀態轉換

貼一張圖,好好記:

技術分享圖片

線程安全的實現方法

  • 互斥同步,加鎖,悲觀方案,保證共享數據同一時刻只有一個線程訪問。,互斥是因,同步是果。
  • 非阻塞同步,CAS,樂觀方案,先進行操作,如果沒有其他線程也進行操作,那麽就操作成功了,如果有其它線程也在操作共享數據,那麽再重試。
  • 無同步方案,一般為純代碼,有一些特性,如不依賴堆上的公用系統資源

鎖優化

  • 自旋鎖與自適應自旋
    假如共享數據只會持續很短的一段時間,為了這段時間進行掛起和恢復線程並不值得,這時我們可以讓後面請求鎖的線程稍等一下,讓線程進行一個忙循環(自旋),這就是所謂的自旋鎖。

因為們有時不值得共享數據到底被鎖了多久,盲目的自旋可能導致性能的損失,JDK1.6之後,系統引入了自適應的自旋,及在一次共享數據被鎖定時,加入系統多次獲得自旋鎖,系統可以允許線程自旋的次數更多時間更久一些。如果多次沒有獲得自旋鎖,那麽系統下次可能會省略掉自旋鎖。

  • 鎖消除
    對一些不可能存在共享數據競爭的鎖進行消除。

  • 鎖粗化
    有時候多個操作都對同一個對象加鎖,頻繁的加鎖也會影響性能,那麽系統就把鎖的同步範圍進行擴展。如StringBuffer()的多個append操作。

  • 偏向鎖
    可以理解為偏袒鎖,鎖會偏向於第一個獲得它的線程,如果接下來的執行過程中,該鎖沒有被其他線程獲取,則持有偏向鎖的線程將永遠不在需要進行同步。

最後

了解並發的內幕是一個高級程序員不可缺少的課程

參考

  • 《深入理解JVM》

Java高效並發