Java中的自旋鎖spinlock詳解
自旋鎖
過程
獲取鎖 訪問共享資源 釋放鎖
自旋鎖
循環(huán)嘗試獲取鎖,不會(huì)放棄CPU時(shí)間片,減傷cup上下文切換,缺點(diǎn)是循環(huán)會(huì)消耗cpu
非自旋鎖
如果獲取不到鎖,讓線程休眠,CPU就可以在這段時(shí)間去做很多其他的事情,直到之前持有這把鎖的線程釋放了鎖,于是CPU再把之前的線程恢復(fù)回來(lái),讓這個(gè)線程再去嘗試獲取這把鎖。若再次失敗,就再次讓線程休眠,若成功,一樣可以成功獲取到同步資源的鎖

如果在獲取自旋鎖時(shí),沒有任何執(zhí)行單元保持該鎖,那么將立即獲取鎖。 如果在獲取鎖時(shí)已經(jīng)有持有者,那么鎖操作將自旋,直到自旋鎖的保持者釋放了鎖。
缺點(diǎn)
自旋鎖一直占用著CPU,他在未獲得鎖的情況下,一直運(yùn)行(自旋),所以占用著CPU,如果不能在很短的時(shí)間內(nèi)獲得鎖,這無(wú)疑會(huì)使CPU效率降低
互斥鎖與自旋鎖區(qū)別
互斥鎖 在未獲得鎖時(shí),cup會(huì)進(jìn)行切換,不會(huì)一直等待
自旋鎖 在未獲得鎖時(shí),一直占用著CPU,一直運(yùn)行(自旋)搶占CUP
在多核機(jī)器中,如果鎖住的“事務(wù)”很簡(jiǎn)單,占用很少時(shí)間,應(yīng)該用自旋鎖,自旋鎖代價(jià)比互斥鎖會(huì)小很多。
”事務(wù)”很快執(zhí)行完畢,自旋的消耗遠(yuǎn)遠(yuǎn)小于陷入sleep和wake的消耗。如果鎖住“事務(wù)”粒度較大,就應(yīng)該使用互斥鎖,因?yàn)槿绻米孕i,那么在“事務(wù)”執(zhí)行過程中自旋很長(zhǎng)時(shí)間還不如使得線程sleep
在單核機(jī)器中。自旋鎖沒有任何意義的,自旋鎖只會(huì)浪費(fèi)唯一核心的cpu 時(shí)間片,這個(gè)時(shí)刻沒有任何線程會(huì)運(yùn)行的。
所以單核機(jī)器中,不論鎖住的”事務(wù)”的粒度大小都要使用。
手寫自旋
public class SpinLockDemo {
AtomicReference<Thread> atomicReference = new AtomicReference<>();
public void lock() {
Thread thread = Thread.currentThread();
System.out.println(Thread.currentThread().getName()+"\t"+"----come in");
// 因?yàn)閍tomicReference沒有set,所以是null,compareAndSet方法比較如果是null,就修改為當(dāng)前線程,如果不是null,就循環(huán)判斷
while (!atomicReference.compareAndSet(null, thread)) {
}
}
public void unLock() {
Thread thread = Thread.currentThread();
// 如果atomicReference存儲(chǔ)的是當(dāng)前線程,就修改為null
atomicReference.compareAndSet(thread,null);
System.out.println(Thread.currentThread().getName()+"\t"+"----task over,unLock...");
}
public static void main(String[] args) {
SpinLockDemo spinLockDemo = new SpinLockDemo();
new Thread(() -> {
spinLockDemo.lock();
// 業(yè)務(wù)邏輯
try { TimeUnit.SECONDS.sleep(5); } catch (InterruptedException e) { e.printStackTrace(); }
spinLockDemo.unLock();
},"A").start();
// 暫停500毫秒,線程A先于B啟動(dòng)
try { TimeUnit.MILLISECONDS.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); }
new Thread(() -> {
spinLockDemo.lock();
spinLockDemo.unLock();
},"B").start();
}
}到此這篇關(guān)于Java中的自旋鎖spinlock詳解的文章就介紹到這了,更多相關(guān)自旋鎖spinlock內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java實(shí)現(xiàn)簡(jiǎn)易學(xué)生管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)簡(jiǎn)易學(xué)生管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-07-07
Java main方法String[]args原理實(shí)例解析
這篇文章主要介紹了Java main方法String[]args原理實(shí)例解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-06-06
Spring Boot3 集成 Spring AI 實(shí)現(xiàn) A
Spring AI的Advisor API是一種聲明式的攔截機(jī)制,借鑒了 Spring AOP 的設(shè)計(jì)理念,允許開發(fā)者在AI交互的生命周期關(guān)鍵節(jié)點(diǎn)插入自定義邏輯,本文全面介紹了Spring Boot集成Spring AI 1.0.0 實(shí)現(xiàn) Advisor 增強(qiáng)機(jī)制的完整流程,感興趣的朋友跟隨小編一起看看吧2026-03-03
java使用HashMap實(shí)現(xiàn)斗地主(有序版)
這篇文章主要為大家詳細(xì)介紹了java使用ArrayList實(shí)現(xiàn)斗地主游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-03-03
升級(jí)springboot中spring框架的版本的實(shí)現(xiàn)方法
本文主要介紹了升級(jí)springboot中spring框架的版本的實(shí)現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2024-08-08
IDEA使用maven創(chuàng)建hibernate項(xiàng)目的實(shí)現(xiàn)步驟(圖文)
本文主要介紹了IDEA使用maven創(chuàng)建hibernate項(xiàng)目的實(shí)現(xiàn)步驟,包括創(chuàng)建Maven項(xiàng)目,配置Hibernate,以及創(chuàng)建實(shí)體類映射到數(shù)據(jù)庫(kù)等步驟,具有一定的參考價(jià)值,感興趣的可以了解一下2023-08-08

