自旋锁spinLock是指尝试获取锁的线程不会立即阻塞, 而是采用循环的方式去尝试获取锁。
- 优点是减少线程上下文切换的消耗;
- 缺点是循环会消耗CPU,会导致ABA问题-[解决方案:带时间戳的原子引用AtomicStampedReference]。
unsafe.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;
}
手写一个自旋锁
/**
* 自旋锁DEMO
* @Author: 小海
* @Description:
* @Date: Create in 00:18 2020-01-30
*/
public class SpinLockDemo {
static AtomicReference<Thread> atomicReference = new AtomicReference<>();
public static void myLock(){
Thread thread = Thread.currentThread();
System.out.println(thread.getName() + " 开始加锁");
while(!atomicReference.compareAndSet(null, thread)){
}
System.out.println(thread.getName() + " 加锁成功");
}
public static void myUnLock(){
Thread thread = Thread.currentThread();
System.out.println(thread.getName() + " 开始解锁");
while(!atomicReference.compareAndSet(thread, null)){
}
System.out.println(thread.getName() + " 解锁成功");
}
public static void main(String[] args) {
new Thread(()->{
myLock();
try {
Thread.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
myUnLock();
}
}, "AA").start();
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(()->{
myLock();
myUnLock();
}, "BB").start();
}
}