Java知識點三:併發與多線程

  • CAS:首先CPU將內存中的將要被修改的數據與預期的值進行比較,如果這兩個值相等,CPU則會將內存中數值替換爲新值,否則不做操作。
  • Synchronized原理:

    Synchronized實現原理
    Synchronized實現原理

    _EntryList、Owner、_WaitSet【1】:進入獲取鎖的線程、指向持有Monitor對象的線程、等待獲取鎖的線程

tip1【2】:對象的內存佈局:對象頭,實例數據,對齊填充(對齊填充並不是必然存在的,僅僅起着佔位符的作用,保證對象頭部分正好是8字節的倍數。)

偏向鎖【3】:無實際競爭,且將來只有第一個申請鎖的線程會使用鎖。

輕量級鎖【3】:無實際競爭,多個線程交替使用鎖;允許短時間的鎖競爭。

重量級鎖:的加鎖、解鎖過程和輕量級鎖差不多,區別是:競爭失敗後,線程阻塞,釋放鎖後,喚醒阻塞的線程

  • AQS【4】:AbustactQueuedSynchronizer的簡稱,它是一個Java提高的底層同步工具類,用一個int類型的變量表示同步狀態,並提供了一系列的CAS操作來管理這個同步狀態。

同步隊列是AQS很重要的組成部分,它是一個雙端隊列,遵循FIFO原則,主要作用是用來存放在鎖上阻塞的線程,當一個線程嘗試獲取鎖時,如果已經被佔用,那麼當前線程就會被構造成一個Node節點假如到同步隊列的尾部,隊列的頭節點是成功獲取鎖的節點,當頭節點線程是否鎖時,會喚醒後面的節點並釋放當前頭節點的引用。

獨佔鎖和共享鎖:獨佔鎖的同步狀態值爲1,即同一時刻只能有一個線程成功獲取同步狀態;共享鎖的同步狀態>1,取值由上層同步組件確定。

重入鎖:基本原理是判斷上次獲取鎖的線程是否爲當前線程,如果是則可再次進入臨界區,如果不是,則阻塞。

  • LongAccumulator:LongAccumulator相比於LongAdder可以提供累加器初始非0值,後者只能默認爲0,另外前者還可以指定累加規則比如不是累加而是相乘,只需要構造LongAccumulator時候傳入自定義雙面運算器就OK,後者則內置累加的規則。
  • blockqueue:線程共享通道,當有新的消息進入隊列後,自動將線程喚醒。例子【5】
  • 臨界資源:是一次僅允許一個進程使用的共享資源; 臨界區:每個進程中訪問臨界資源的那段代碼稱爲臨界區,每次只允許一個進程進入臨界區,進入後,不允許其他進程進入。
  • synchronized,lock比較:

(1)來源: lock是一個接口,而synchronized是java的一個關鍵字,synchronized是內置的語言實現;

(2)異常是否釋放鎖: synchronized在發生異常時候會自動釋放佔有的鎖,因此不會出現死鎖;而lock發生異常時候,不會主動釋放佔有的鎖,必須手動unlock來釋放鎖,可能引起死鎖的發生。(所以最好將同步代碼塊用try catch包起來,finally中寫入unlock,避免死鎖的發生。)

(3)是否響應中斷 :lock等待鎖過程中可以用interrupt來中斷等待,而synchronized只能等待鎖的釋放,不能響應中斷;

(4)是否知道獲取鎖 :Lock可以通過trylock來知道有沒有獲取鎖,而synchronized不能;

(5)Lock可以提高多個線程進行讀操作的效率。(可以通過readwritelock實現讀寫分離)

在性能上來說,如果競爭資源不激烈,兩者的性能是差不多的,而當競爭資源非常激烈時(即有大量線程同時競爭),此時Lock的性能要遠遠優於synchronized。所以說,在具體使用時要根據適當情況選擇。

(6)synchronized使用Object對象本身的wait 、notify、notifyAll調度機制,而Lock可以使用Condition進行線程之間的調度。

(7)synchronized原始採用的是CPU悲觀鎖機制,即線程獲得的是獨佔鎖。而Lock用的是樂觀鎖方式。

  • lock使用場景:

1.某個線程在等待一個鎖的控制權的這段時間需要中斷 

2.需要分開處理一些wait-notify,ReentrantLock裏面的Condition應用,能夠控制notify哪個線程 

3.具有公平鎖功能,每個到來的線程都將排隊等候

  • ReentrantLock實現原理:【7】
  • 徹底理解ThreadLocal:【8】
  • Java 9 Reactive Streams【9】:取消訂閱可能會導致主線程邏輯死循環、當發佈者以比訂閱者消費更快的速度生成消息時,會產生背壓

  • Java實現生產者-消費者模型【10】:

1、BlockingQueue

2、wait && notify

3、簡單的Lock && Condition(高級:生產、消費鎖分離,以此讓優化消費者與消費者(或生產者與生產者)之間是串行的;消費者與生產者之間是並行的,buffer在頭部出隊,尾部入隊)

4、Semaphore

  • 線程池的處理流程和原理:

線程池處理任務流程
線程池處理任務流程

 

  • Synchronized與ReentrantLock有什麼不同,各適用什麼場景:在確實需要一些 synchronized 所沒有的特性的時候,比如時間鎖等候、可中斷鎖等候、無塊結構鎖、多個條件變量或者輪詢鎖。
  • ReentrantReadWriteLock實現原理【13】:表示兩個鎖,一個是讀操作相關的鎖,稱爲共享鎖;一個是寫相關的鎖,稱爲排他鎖

【1】https://www.cnblogs.com/monkey0307/p/9667606.html    《JAVA對象內存結構》

【2】https://blog.csdn.net/u010126792/article/details/82968521  《JVM學習之對象內存佈局,對象頭》

【3】https://www.jianshu.com/p/36eedeb3f912    《淺談偏向鎖、輕量級鎖、重量級鎖》

【4】https://blog.csdn.net/zhangdong2012/article/details/79983404    《Java併發-AQS及各種Lock鎖的原理》

【5】https://www.jianshu.com/p/024a36b83099    《併發編程-BlockQueue線程容器》

【6】https://blog.csdn.net/tingfeng96/article/details/52219649    《synchronized 和Lock區別》

【7】https://www.jianshu.com/p/b6efbdbdc6fa    《ReentrantLock實現機制(CLH隊列鎖)》

【8】https://www.cnblogs.com/xzwblog/p/7227509.html    《徹底理解ThreadLocal》

【9】https://blog.csdn.net/why_still_confused/article/details/82351960    《Java 9 Reactive Streams》

【10】https://www.jianshu.com/p/3d4cbb969063    《Java實現生產者-消費者模型》

【11】https://www.jianshu.com/p/519803f392dc    《線程池的處理流程和原理》

【12】https://www.ibm.com/developerworks/cn/java/j-jtp10264/index.html    《JDK 5.0 中更靈活、更具可伸縮性的鎖定機制》

【13】https://www.cnblogs.com/faunjoe88/p/7928757.html    《輕鬆掌握java讀寫鎖(ReentrantReadWriteLock)的實現原理》

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章