深入理解java虚拟机--线程安全与锁优化
深入理解java虛擬機(jī)--線程安全與鎖優(yōu)化
- 面向過程編程思想和面向?qū)ο缶幊趟枷?/li>
- java語言中的線程安全
- 線程安全的實現(xiàn)方法
- 鎖優(yōu)化
面向過程編程思想和面向?qū)ο缶幊趟枷?/h2>
面向過程編程思想:站在計算機(jī)的角度,以算法為核心,數(shù)據(jù)是客體,程序代碼處理數(shù)據(jù)。
面向?qū)ο缶幊趟枷?#xff1a;站在現(xiàn)實世界的角度,數(shù)據(jù)和行為視為對象的一部分。
java語言中的線程安全
5類共享數(shù)據(jù)類別:1.不可變;2.絕對線程安全;3.相對線程安全;4.線程兼容;5.線程對立。
不可變帶來的安全性是最簡單和最純粹的。基本數(shù)據(jù)類型,final關(guān)鍵字修飾;共享數(shù)據(jù)是一個對象,對象的行為用final修飾。
定義:當(dāng)多個線程訪問一個對象時,如果不用考慮這些線程在運行時環(huán)境下的調(diào)度和交替執(zhí)行,也不需要進(jìn)行額外的同步,或者在調(diào)用方進(jìn)行任何其他的協(xié)調(diào)操作,調(diào)用這個對象的行為都可以獲得正確的結(jié)果,那這個對象是線程安全的。
單獨操作是線程安全的;需要額外的同步手段(特定順序的連續(xù)調(diào)用)。
例子:Vector的get()、remove()、size()等方法;其他類如:HashTable等。
本身不是線程安全的;需要正確使用同步手段。
例子:Vector的get()、remove()、size()等方法;其他類如:ArrayList、HashMap等。
無論是采取何種同步措施,都無法達(dá)到線程安全的。
例子:Thread類的suspend()和resume();其他類如:System類的setInt()、setOut()和runFinalizersOnExit()等。
線程安全的實現(xiàn)方法
3種實現(xiàn)方法:1.互斥同步;2.非阻塞同步;3.無同步方案。
也稱阻塞同步;互斥是方法,同步是目的;互斥的實現(xiàn)方式主要有三種:臨界區(qū),互斥量,信號量。實現(xiàn)同步手段:synchronized和ReentrantLock。
-
synchronized:原生語法層面的互斥;關(guān)鍵字經(jīng)過編譯后在同步塊前后形成monitorenter和monitorexit兩個字節(jié)碼指令,這兩字字節(jié)碼指令都需要一個reference類型的參數(shù)來指明要鎖定和解鎖的對象;如果synchronized修飾的實例方法則去取對應(yīng)的對象實例,如果修飾的是類方法,則去取Class對象所為鎖對象。有兩點要注意的:1.synchronized同步塊對同一條線程來說是可重入的,不會出現(xiàn)自己把自己鎖死的情況;2.同步塊在已進(jìn)入的線程執(zhí)行完之前,會阻塞后面其他線程的進(jìn)入。
-
ReentrantLock:API層面的互斥;相對于synchronized來說有三個高級特性:1.等待可中斷;2.可實現(xiàn)公平鎖;3.鎖可以綁定多個條件;
-
synchronized和ReentrantLock吞吐量比較
jdk1.5版本:ReentrantLock>synchronized;
jdk1.6后版本:synchronized、ReentrantLock兩者持平; -
處理問題方式角度:互斥同步是悲觀策略。
阻塞和喚醒一個線程,需要從用戶態(tài)轉(zhuǎn)換到核心態(tài),消耗性能。
-
定義
基于沖突檢測的樂觀并發(fā)策略,先進(jìn)行操作,如果沒有其他線程的競爭共享數(shù)據(jù),那操作就是成功了;如果共享數(shù)據(jù)有爭用,產(chǎn)生了沖突,那就再采取其他的補(bǔ)充措施(最常見的補(bǔ)償措施就是不斷的重試,直到成功為止),這種樂觀的策略很多實現(xiàn)都不需要把線程掛起。
-
處理問題方式角度:非阻塞同步是樂觀策略。
-
CAS指令
內(nèi)存位置(V)、舊的預(yù)期值(A)、新值(B);
CAS指令執(zhí)行時,當(dāng)且僅當(dāng)V符合舊預(yù)期值A(chǔ)時,處理器用新值B更新V的值,否則它就不執(zhí)行更新,但是無論是否更新了V的值,都會返回V的舊值,上述的處理過程是一個原子操作。CAS漏銅,ABA問題:
如果一個變量V初次讀取的時候是A值,并且在準(zhǔn)備賦值的時候檢查到它仍然是A值,那我們就能說它的值沒有被其他線程改變過了嗎?如果在這段期間它的值曾經(jīng)被改成了B,后來又被改成了A,那CAS操作就會誤認(rèn)為它從來沒有被改變過。
無同步方案
2類:1.可重入代碼;2.線程本地存儲。
可重入代碼
3個特征:不依賴存儲在堆上的數(shù)據(jù)和公用的系統(tǒng)資源、用到的狀態(tài)量都是由參數(shù)傳入、不調(diào)用非可重入的方法。
線程本地存儲
例子:生產(chǎn)者-消費者:Web交互模型中的"一個請求對應(yīng)一個服務(wù)器線程"的處理方式。
鎖優(yōu)化
5種鎖優(yōu)化:1.自旋鎖和自適應(yīng)自旋;2.鎖消除;3.鎖粗化;4.輕量級鎖;5.偏向鎖。
- 自旋鎖定義
是指嘗試獲取鎖的線程不會立即阻塞,而是采用循環(huán)的方式去嘗試獲取鎖。 - 自適應(yīng)自旋定義
- 自旋的時間不在固定,由前一次在同一個鎖上的自旋時間及鎖的擁有者的狀態(tài)決定。
- 原因
- 掛起線程和喚醒線程會消耗處理器時間
- 共享數(shù)據(jù)的鎖定狀態(tài)很多情況只會持續(xù)很短的時間
- 定義
指在虛擬機(jī)即時編譯器在運行時,對一些代碼上要求同步,但是被檢測到不可能存在共享數(shù)據(jù)競爭的鎖進(jìn)行消除。
鎖粗化
范圍擴(kuò)大,如果虛擬機(jī)探測到有這樣的一串零碎的操作都是對同一個對象加鎖,將會把加鎖同步的范圍擴(kuò)展(粗化)到整個操作序列的外部,這樣只需要加鎖一次就可以了。
輕量級鎖
- 沒有多線程的競爭前提下;減少傳統(tǒng)的重量級所使用操作系統(tǒng)互斥量產(chǎn)生的性能消耗。
- Mark Word
- 消除數(shù)據(jù)在無競爭情況下的同步原語,進(jìn)一步提高程序的運行性能。
- 不用做CAS操作。
總結(jié)
以上是生活随笔為你收集整理的深入理解java虚拟机--线程安全与锁优化的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 学习进度条07
- 下一篇: webstorm破解方法