實例講解Java 自旋鎖
一直以來不是怎么清楚自旋鎖,最近有點時間,好好的學習了一下;
所謂的自旋鎖在我的理解就是多個線程在嘗試獲取鎖的時候,其中一個線程獲取鎖之后,其他的線程都處在一直嘗試獲取鎖的狀態(tài),不會阻塞?。?!那么什么叫做一直嘗試獲取鎖呢?就是一個循環(huán),比較經(jīng)典的是AtomicInteger中的一個updateAndGet方法,下圖所示(當然也可以直接看unsafe類中的getAndAddInt等類似方法);
我們可以看出在while循環(huán)中使用CAS去嘗試更新一個變量,如果更新失敗,就會一直在這個循環(huán)中一直在嘗試;成功的話,就可以到最后的return語句;
由此我們可以大概知道如果自旋的線程過多,那么CPU的資源就會被大量消耗?。?!

順便提一個東西叫做原子引用,官方提供了AtomicInteger,AtomicBoolean等原子類,那么如果我們自己定義的類也需要有原子性怎么辦呢?所以官方提供了一個AtomicReference類,可以將我們自己定義的類封裝一下,就成了我們自己的原子類,例如AtomicReference<Student> atomicReference = new AtomicReference<>();,然后我們對Student的實例進行CAS各種CAS操作;
栗子:
package TestMain;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
@Slf4j
public class TestMain80 {
//一個Thread類的原子引用
AtomicReference<Thread> atomicReference = new AtomicReference<>();
//加鎖的方法
public void myLock() {
Thread currentThread = Thread.currentThread();
log.info("myLock--Thread:{}", currentThread.getName());
//這個就是自旋鎖的核心,利用CAS比較當前原子引用中是否為null,如果是null,就把當前線程A放到里面去,
// 此時線程B再到這里,那么就會CAS失敗,一直在while循環(huán)中
while (!atomicReference.compareAndSet(null, currentThread)) {
}
}
//解鎖的方法
public void myUnlock() {
Thread currentThread = Thread.currentThread();
//CAS比較原子引用中是不是線程A,是的話就更新為null,此時在上面while中一直在自旋的線程B就可以跳出來了
atomicReference.compareAndSet(currentThread, null);
log.info("myUnlock--Thread:{}", currentThread.getName());
}
public static void main(String[] args) {
TestMain80 testMain80 = new TestMain80();
//線程A,首先加鎖,然后等3秒中,然后釋放鎖
new Thread(() -> {
testMain80.myLock();
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
testMain80.myUnlock();
}, "A").start();
//主線程等1秒,保證A線程先執(zhí)行
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
//線程B,加鎖再釋放鎖
new Thread(() -> {
testMain80.myLock();
testMain80.myUnlock();
}, "B").start();
}
}

上面的就是一個自旋鎖的栗子,執(zhí)行結果中首先是執(zhí)行A線程的myLock方法,獲取鎖成功,之后的B線程雖然也會執(zhí)行mylock方法,但是會在while循環(huán)中一直阻塞,直到線程A調(diào)用了myUnlock方法釋放鎖,最后兩行才會打印出來;
以上就是實例講解Java 自旋鎖的詳細內(nèi)容,更多關于Java 自旋鎖的資料請關注腳本之家其它相關文章!
相關文章
springboot整合JPA訪問Mysql的實現(xiàn)方法
本文主要介紹了springboot整合JPA訪問Mysql的實現(xiàn)方法,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-02-02
使用Java的Spring框架編寫第一個程序Hellow world
這篇文章主要介紹了Java的Spring框架并用其開始編寫第一個程序Hellow world的方法,Spring是Java的SSH三大web開發(fā)框架之一,需要的朋友可以參考下2015-12-12
Java如何解決發(fā)送Post請求報Stream?closed問題
這篇文章主要介紹了Java如何解決發(fā)送Post請求報Stream?closed問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-06-06
java中orElse和orElseGet方法區(qū)別小結
這篇文章主要給大家介紹了關于java中orElse和orElseGet方法區(qū)別的相關資料,兩者之間的區(qū)別細微,但是卻在某些場景下顯的很重要,文中通過代碼介紹的非常詳細,需要的朋友可以參考下2023-10-10

