CAS和Unsafe
Posted z啵唧啵唧
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CAS和Unsafe相关的知识,希望对你有一定的参考价值。
五、CAS
CAS实现锁的原理
@Slf4j(topic = "c.LockCas")
public class LockCas
/**
* 0表示没有加锁
* 1表示加锁
*/
private AtomicInteger state = new AtomicInteger(0);
public void lock()
//实际上在这个地方会存在空运转的问题
while (true)
//cas操作,采用了cas的原理实现
if (state.compareAndSet(0, 1))
break;
public void unlock()
log.debug("unlock...");
//解锁将state的值设置为0即可
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方法的时候发现修改不了,因为线程1先一步调用了lock方法并且将state的值改成了1
//此时线程2只能等线程1睡眠时间过后调用了unlock方法将state的值改为了0,才能此时线程2才能调用lock方法进行加锁
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
//获得unsafe对象
//获得unsafe成员变量
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
//获得unsafe对象
//获得unsafe成员变量
Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
//设置允许访问私有变量
theUnsafe.setAccessible(true);
Unsafe unsafe = (Unsafe)theUnsafe.get(null);
//1、获取域的偏移地址
long idOffset = unsafe.objectFieldOffset(Teacher.class.getDeclaredField("id"));
long nameOffset = unsafe.objectFieldOffset(Teacher.class.getDeclaredField("name"));
Teacher t = new Teacher();
//2、执行cas操作
unsafe.compareAndSwapInt(t,idOffset,0,1);
unsafe.compareAndSwapObject(t,nameOffset,null,"张三");
//3、验证
System.out.println(t);
@Data
class Teacher
volatile int id;
volatile String name;
以上是关于CAS和Unsafe的主要内容,如果未能解决你的问题,请参考以下文章
自己利用unsafe的cas实现的AtomicInteger