馬士兵多線程直播筆記(上)

線程與進程

  • 進程:操作系統分配資源的基本單位
  • 線程:CPU調度(執行)的基本單位。共享進程的資源。

  一個CPU同一時間只能執行一個線程,表象是線程切換(Context Switch)。對CPU來說,寄存器存數、ALU計算、PC(程序計數器)記錄位置。

線程切換過程

  線程時間結束後,當前整個狀態(PC、寄存器等)全部拿出去放到緩存或者內存中,也成爲保護現場

線程一定是越多越好嗎

  不,過多線程的切換需要資源較多。

JVM級別線程

  Class啓動的Thread,JVM級別線程,對應操作系統內核線程

  當然JVM沒有規定一一對應關係,但是HotSpot實現,JVM線程:內核線程=1:1。可參見:https://www.cnblogs.com/MrSaver/p/12987454.html。還是一種線程模型是,用戶級別線程,通過虛擬的PC、虛擬寄存器,管理屬於用戶空間的線程,輕量級的線程——協程,纖程。短計算場景下優於內核線程

注:JDK1.2之前,Synchronized由OS幫忙管理,非常的重量級鎖。

鎖的本質

  鎖定對象,可參見:https://www.cnblogs.com/MrSaver/p/13024132.html。鎖上面有等待隊列,以實現調度。

CAS

  這樣的代碼,結果一定不是一百萬。注意,加Volatile沒有用!

    

  CAS(Compare And Swap),最底層是native代碼,由操作系統負責實現。樂觀鎖,馬士兵稱之爲自旋鎖,本質死循環,但是一定能有執行成功的時候!

  

問1:如何處理ABA問題?

答:加版本處理

問2:爲什麼會比重量級鎖效率高?

答:僞命題,未必,即使經歷過用戶空間的優化,具體問題具體分析。

  自旋是消耗CPU資源的,如果鎖的時間長,或者自旋線程多,CPU會被大量消耗。重量級鎖有等待隊列,所有拿不到所得進入等待隊列,不需要消耗CPU資源。 

問3:原子性如何實現!

答:硬件指令集提供,見下代碼!

  

  進入之後,彙編命令:CMPXCHG。

  

JOL(Java Object Layout)與鎖

  對象的內存佈局打印信息如下:

  

  當我們給對象加Synchronized鎖後,再打印JOL信息:

  

  MarkWord鎖內容具體如下:

  

偏向鎖

  偏向鎖也是JDK1.6中引入的一項鎖優化。目的是在無競爭的情況下把整個同步都消除掉,包括CAS操作。這個鎖會偏向於第一個獲得它的線程,如果在接下來的執行過程中,該鎖沒有被其他線程獲取,則持有偏向鎖的線程講永遠不需要進行同步。但是一旦有另外一個線程去嘗試獲取這個鎖時,偏向模式就宣告結束,撤銷偏向後恢復到未鎖定(01)或輕量級鎖定(00)狀態。

  在統計學分析下,一個鎖大多數情況下只有一個線程再用,比如Vector、StringBuffer很多方法都會有Synchronized,但是通常業務下只有一個線程在用。

鎖升級過程

  總體路徑:無鎖——偏向鎖——自旋鎖——重量級鎖。

  多線程競爭下,偏向鎖(放在MarkWord)撤銷先變爲自旋鎖(CAS方式),重度競爭的情況下,線程較多的情況下,升級爲重量級鎖。

  

 

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