五、CAS
CAS实现锁的原理
@Slf4j(topic = "c.LockCas")
public class LockCas {
private AtomicInteger state = new AtomicInteger(0);
public void lock() {
while (true) {
if (state.compareAndSet(0, 1)) {
break;
}
}
}
public void unlock() {
log.debug("unlock...");
state.set(0);
}
public static void main(String[] args) {
LockCas lock;
lock = new LockCas();
new Thread(() -> {
log.debug("begin...");
lock.lock();
try {
log.debug("lock...");
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}).start();
new Thread(() -> {
log.debug("begin...");
lock.lock();
try {
log.debug("lock...");
} finally {
lock.unlock();
}
}).start();
}
}
Unsafe类
- Unsafe对象提供了非常底层,操作内存,线程的方法,Unsafe对象不能直接调用,只能通过反射获得
- 如AtomicInteger底层的一些方法实际上就是调用的就是unsafe类的一些方法
- LockSupport类底层的park、unpark调用的也是unsafe对象的方法
unsafe对象的获取
public class TestUnsafe {
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
theUnsafe.setAccessible(true);
Unsafe unsafe = (Unsafe)theUnsafe.get(null);
System.out.println(unsafe);
}
}
unsafe CAS操作
public class TestUnsafe {
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
theUnsafe.setAccessible(true);
Unsafe unsafe = (Unsafe)theUnsafe.get(null);
long idOffset = unsafe.objectFieldOffset(Teacher.class.getDeclaredField("id"));
long nameOffset = unsafe.objectFieldOffset(Teacher.class.getDeclaredField("name"));
Teacher t = new Teacher();
unsafe.compareAndSwapInt(t,idOffset,0,1);
unsafe.compareAndSwapObject(t,nameOffset,null,"张三");
System.out.println(t);
}
}
@Data
class Teacher{
volatile int id;
volatile String name;
}
