java自旋锁使用_10.Java锁之自旋锁
概念
自旋鎖(spinlock):是指嘗試獲取鎖的線程不會立即阻塞,而是采用循環的方式去嘗試獲取鎖。之前學過的CAS,底層使用的就是自旋鎖,自旋就是多次嘗試,多次訪問,不會阻塞的狀態就是自旋。
優缺點
優點:循環比較獲取直到成功,沒有類似wait的阻塞。還能減少線程上下文切換的消耗
缺點:當不斷自旋的線程越來越多的時候,會因為執行while循環不斷的消耗CPU資源
手寫自旋鎖
自旋的本質就是CAS方法和while循環public class SpinLockDemo {
// 原子引用線程
AtomicReference atomicReference = new AtomicReference<>();
public void myLock() {
Thread thread = Thread.currentThread(); // 返回對當前正在執行的線程對象的引用
System.out.println(Thread.currentThread().getName() + "進來了");
/* 首個線程進來,發現atomicReference是null,就變為這個線程。然后取反變為false,跳出循環等待。
如果發現衛生間里面還有人,就一直循環一直等,直到衛生間里面沒人。 */
while (!atomicReference.compareAndSet(null, thread)) {
//沒跳出就一直循環
}
}
public void myUnlock() {
Thread thread = Thread.currentThread();
// 我出去要解鎖,然后變為null給下一個人用
atomicReference.compareAndSet(thread, null);
System.out.println(Thread.currentThread().getName() + "調用myUnlock方法");
}
測試public static void main(String[] args) throws InterruptedException {
SpinLockDemo spinLockDemo = new SpinLockDemo();
// 我A線程進去占用這把鎖,然后霸占5s
new Thread(() -> {
spinLockDemo.myLock();
TimeUnit.SECONDS.sleep(5);
spinLockDemo.myUnlock();
}, "線程A").start();
// 主線程main暫停1s,保證A線程先啟動
TimeUnit.SECONDS.sleep(1);
// 我B線程再進去循環等待這把鎖
new Thread(() -> {
spinLockDemo.myLock();
spinLockDemo.myUnlock();
}, "線程B").start();
}
運行結果線程A進來了 //A進來了,A要占用5s
線程B進來了 //B也進來了,發現衛生間有人,循環等待A出來
線程A調用myUnlock方法 //A出來了
線程B調用myUnlock方法 //B占用完鎖,也出來了
總結
以上是生活随笔為你收集整理的java自旋锁使用_10.Java锁之自旋锁的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 在使用vue脚手架之前你必须掌握的:vu
- 下一篇: RSA加密 - Java