手写自旋锁,根据CAS思想实现,AtomicReference,AtomicInteger等底层均使用了CAS
AtomicReference
-
value值用volatile关键字,实现可见性
private volatile V value;
-
compareAndSet方法
public final boolean compareAndSet(V expect, V update) {
return unsafe.compareAndSwapObject(this, valueOffset, expect, update);
}
- getAndUpdate方法(CAS)
public final V getAndUpdate(UnaryOperator<V> updateFunction) {
V prev, next;
do {
prev = get();
next = updateFunction.apply(prev);
} while (!compareAndSet(prev, next));
return prev;
}
根据上述源码可知:
AtomicInteger,AtomicReference等具有原子性均没有使用Lock、synchronized等,而是使用了自旋锁实现原子性
UnSafe类
封装了很多native方法,此处列出部分
public native int getInt(Object var1, long var2);
public native void putInt(Object var1, long var2, int var4);
public native Object getObject(Object var1, long var2);
public native void putObject(Object var1, long var2, Object var4);
AtomicInteger
底层和AtomicReference类似,针对Integer类设计的原子类
- getAndIncrement()
public final int getAndIncrement() {
return unsafe.getAndAddInt(this, valueOffset, 1);
}
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.xmm.juc.lockSyn;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicReference;
/**
* Author:XMH
* Date:2020/8/8 19:44
* 利用CAS思想手写自旋锁
*/
public class SpinLock {
private AtomicReference<Thread> atomicReference = new AtomicReference<>(null);
public static void main(String[] args) {
SpinLock spinLock = new SpinLock();
List<String> list = new ArrayList<>();
for (int i = 0; i < 100; i++) {
new Thread(()->{
spinLock.onLock();
try {
list.add(UUID.randomUUID().toString().substring(0,5));
System.out.println(list);
} catch (Exception e) {
e.printStackTrace();
} finally {
spinLock.unLock();
}
},i+"").start();
}
}
public void onLock() {
int count=0;
while(!atomicReference.compareAndSet(null,Thread.currentThread())){
if (count>10){
//循环到一定的次数时,为避免长时间占用时间cpu资源,使当前线程释放时间片,重新成为就绪状态竞争cpu调度
Thread.yield();
}
count++;
}
}
public void unLock() {
atomicReference.compareAndSet(Thread.currentThread(),null);
}
}