java併發編程知識點總結

和之前一篇多線程文章類似,這裏沒有什麼邏輯順序就是一些知識點,也不是很深入,見諒!


1、不是有越多的線程程序運行的越快,因爲在併發編程時,會有更多的上下文切換,死鎖等問題。

2、上下文切換:CPU通過時間片 分配算法來循環執行任務,當前任務執行完一個時間片之後會切換到下一個任務,但是又要保存上一個任務的狀態,以便下一次可以加載到上一狀態,所以任務從保存到在加載的過程叫做上下文切換。

3、如何減少上下文切換?   

無鎖併發編程:多線程因爲有所會出現很多競爭,所以儘量避免鎖,EG:將數據的ID按照hash算法取模分段,不同的線程處理不同的段的數據。

CAS算法:Java的Atomic包使用CAS算法來更新數據,不需加鎖。

使用最少線程:避免創建不需要的線程。

協程:在單線程裏實現多任務調度,並在單線程裏維持多個任務間的切換。

4.避免死鎖的辦法:

  避免一個線程同時獲得多個鎖

避免一個線程在鎖內同時佔用多個資源,儘量保證每個鎖只佔用一個資源

嘗試使用定時鎖,使用lock.tryLock(timeout)來代替使用內部鎖機制

對於數據庫鎖,加鎖和解鎖必須在一個數據庫連接裏,否則會出現解鎖失敗的情況

 

Java併發機制的底層實現、

Java代碼編譯後會變成Java字節碼,字節碼被類加載器加載到jvm裏,jvm執行字節碼,最終轉換成彙編指令在CPU上運行,Java所使用的併發 機制依賴jvm的實現和CPU的指令。

volatile

volatile的應用:volatile是輕量級的Synchronized,他保證了共享變量的可見性,(可見性是指:當一個線程修改一個共享變量的值時,另一個線程可以讀取這個修改的值)、恰當使用volatile會比Synchronize效率高,因爲volatile不會有上下文切換和調度。

Volatile的定義:允許線程訪問共享變量,爲了確保共享變量可以一致的更新,應該通過排它鎖單獨的獲得這個變量。

1.Volatile原理:1.Lock前綴指令會引起處理器緩存寫到內存:

2.一個處理器的緩存寫到內存會導致其他處理器的緩存無效。

volatile的優化:jdk7中增加了一個隊列集合類:LinkedTransferQueue  他在使用volatile變量時,通過追加字節的方法來優化隊列的出棧和入棧性能。

那麼他是如何優化的呢?原來緩存行的大小是64字節,所以使用追加的方法填充緩存行,這樣的話就避免了頭結點和尾節點在一行,這樣在修改時也不會相互鎖定。

 

在兩種情況下不能用這種優化方法:1,當緩存行的大小不是64,2.當沒有對共享變量頻繁的寫

 

Synchronize

Synchronize也被稱爲重量級鎖,因爲在獲得鎖和釋放鎖都會帶來性能消耗

Synchronize實現鎖有三種表現形式:

1.對於普通的同步方法,鎖的是當前的實例變量

2.對於靜態的同步方法,鎖的是當前類的class對象

3.對於同步同步方法塊,鎖的是{}配置的對象。

 

 

鎖的升級與對比:爲了減少鎖申請和釋放帶來的性能消耗,引入了“偏向鎖”“輕量級鎖”。

鎖一共有四種狀態:無鎖狀態,偏向鎖狀態,輕量級鎖狀態,重量級鎖狀態。

鎖可以升級但是不能降級。

 

  偏向鎖:由於大多數情況下鎖其實不具有競爭狀態,所以出現了該鎖,基本的思想是:當一個線程訪問一個同步塊並且獲取鎖時,會在對象頭和幀棧中的鎖記錄裏存儲鎖偏向的線程ID,以後該線程在進入和退出該同步塊時,不需要用CAS來加鎖和解鎖,只需要簡單測試一下對象頭裏的MarkWord裏是否存了指向當前線程的偏向鎖,要是有,表示已經獲得鎖;

 

偏向鎖的撤銷,使用了一種等到有競爭才釋放的機制,也就是說,當其他線程請求的時候纔會釋放。同時釋放的時候需要等到安全點,即在這個點上沒有正在執行字節碼。偏向鎖是自動開啓的,要實現兩關閉,則通過-XX:BiasedLockingStartupDelay=0來設置。設置之後就默認進入輕量級鎖。


 

鎖的優缺點:

優點

缺點

適用場景

偏向鎖

加鎖和解鎖不需要額外的開銷,和執行費同步方法只有納秒級的差別。

若線程之間存在鎖競爭,會帶來額外的鎖撤銷的消耗。

適用於只有一個線程訪問同步塊的場景。

輕量級鎖

競爭的線程不會阻塞,提高了程序的響速度

如果始終得不到鎖競爭的線程會陷入自旋,會消耗CPU

追求響應時間 同步塊執行速度非常快

重量級鎖

線程競爭不會自旋

線程阻塞,響應時間慢

追求吞吐量

同步塊執行速度較長

 

原子操作

原子操作是不能被分割的一系列操作。

基於緩存行加鎖和總線加鎖的方式來實現原子操作

緩存鎖鎖掉了內存和CPU之間的通信,開銷比較大,所以現在用的是緩存行加鎖。

但有兩種情況不會使用緩存行鎖:

操作的數據不能被緩存或則一個緩存行不夠存儲

有些處理器不支持緩存鎖定


Java如何實現原子操作:可以通過鎖和循環CAS來實現。

 

 

發佈了43 篇原創文章 · 獲贊 15 · 訪問量 10萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章