自旋锁spinlock
重点:尝试获取锁的线程不会立即阻塞,而是采用循环的方式去尝试获取锁,这样的好处是减少线程上下文切换的消耗,不会堵塞。缺点是循环会消耗CPU
public final int getAndAddInt(Object var1, long var2, int var4) {
int var5;
do {
var5 = this.getIntVolatile(var1, var2);
} while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));
return var5;
}
推荐阅读
手敲自旋锁:
代码:
package com.juc.lock;
import java.util.Date;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
/**
* Created by 乐心湖 on 2020/5/5 19:49
*/
public class SpinLockDemo {
/**
* 原子引用线程
*/
AtomicReference<Thread> atomicReference = new AtomicReference<>();
/**
* 自己写一个锁
*/
public void myLock() {
Thread thread = Thread.currentThread();
System.out.println(thread.getName() + "\t come in !" + new Date());
// 交换不成功则一直自旋
while (!atomicReference.compareAndSet(null, thread)) {
}
}
/**
* 解锁
*/
public void myUnLock() {
Thread thread = Thread.currentThread();
atomicReference.compareAndSet(thread, null);
System.out.println(thread.getName() + "\t go out !" + new Date());
}
public static void main(String[] args) {
SpinLockDemo spinLockDemo = new SpinLockDemo();
new Thread(() -> {
spinLockDemo.myLock();
try {
// 线程1在6秒后才释放锁
TimeUnit.SECONDS.sleep(6);
} catch (InterruptedException e) {
e.printStackTrace();
}
spinLockDemo.myUnLock();
}, "Thread1").start();
// 等两秒才开始线程2
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(() -> {
spinLockDemo.myLock();
spinLockDemo.myUnLock();
}, "Thread2").start();
}
}
Thread1 come in !Tue May 05 20:02:54 CST 2020
Thread2 come in !Tue May 05 20:02:56 CST 2020
Thread1 go out !Tue May 05 20:03:00 CST 2020
Thread2 go out !Tue May 05 20:03:00 CST 2020
从结果可以看出,在线程1还没有释放锁时,线程2无法执行操作,仅仅是进入后不断循环直到线程1释放锁。
这就是自旋锁的妙处。
版权属于:乐心湖's Blog
本文链接:https://www.xn2001.com/archives/457.html
声明:博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!
2 comments
看到Java就头疼,大佬们都是如何学习的啊。我学Java巨吃力
这个,我感觉Java用起来比前端轻松得多,::quyin:amazing:: 应该是各有喜好无需强求。