Java中的自旋鎖spinlock詳解
自旋鎖
過程
獲取鎖 訪問共享資源 釋放鎖
自旋鎖
循環(huán)嘗試獲取鎖,不會(huì)放棄CPU時(shí)間片,減傷cup上下文切換,缺點(diǎn)是循環(huán)會(huì)消耗cpu
非自旋鎖
如果獲取不到鎖,讓線程休眠,CPU就可以在這段時(shí)間去做很多其他的事情,直到之前持有這把鎖的線程釋放了鎖,于是CPU再把之前的線程恢復(fù)回來,讓這個(gè)線程再去嘗試獲取這把鎖。若再次失敗,就再次讓線程休眠,若成功,一樣可以成功獲取到同步資源的鎖
如果在獲取自旋鎖時(shí),沒有任何執(zhí)行單元保持該鎖,那么將立即獲取鎖。 如果在獲取鎖時(shí)已經(jīng)有持有者,那么鎖操作將自旋,直到自旋鎖的保持者釋放了鎖。
缺點(diǎn)
自旋鎖一直占用著CPU,他在未獲得鎖的情況下,一直運(yùn)行(自旋),所以占用著CPU,如果不能在很短的時(shí)間內(nèi)獲得鎖,這無疑會(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)文章
Eclipse使用maven搭建spring mvc圖文教程
這篇文章主要為大家分享了Eclipse使用maven搭建spring mvc圖文教程,感興趣的小伙伴們可以參考一下2016-05-05SpringBoot在一定時(shí)間內(nèi)限制接口請(qǐng)求次數(shù)的實(shí)現(xiàn)示例
在項(xiàng)目中,接口的暴露在外面,很多人就會(huì)惡意多次快速請(qǐng)求,本文主要介紹了SpringBoot在一定時(shí)間內(nèi)限制接口請(qǐng)求次數(shù)的實(shí)現(xiàn)示例,具有一定的參考價(jià)值,感興趣的可以了解一下2022-03-03Java中大數(shù)據(jù)推薦算法使用場(chǎng)景分析
在Java中實(shí)現(xiàn)大數(shù)據(jù)推薦算法時(shí),通常會(huì)使用一些開源的機(jī)器學(xué)習(xí)庫,如Apache Mahout、Weka、DL4J(DeepLearning4j,用于深度學(xué)習(xí))或者Spark MLlib(用于在Spark集群上運(yùn)行),這篇文章主要介紹了Java中可以用的大數(shù)據(jù)推薦算法,需要的朋友可以參考下2024-06-06Spring?IOC容器Bean管理的完全注解開發(fā)放棄配置文件
這篇文章主要為大家介紹了Spring?IOC容器的Bean管理完全注解開發(fā)放棄配置文件,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-05-05利用Java的Struts框架實(shí)現(xiàn)電子郵件發(fā)送功能
這篇文章主要介紹了利用Java的Struts框架實(shí)現(xiàn)電子郵件發(fā)送功能,Struts框架是Java的SSH三大web開發(fā)框架之一,需要的朋友可以參考下2015-12-12