UnSafe学习笔记

前言

  1. 锁会导致线程上下文切换和重新调度开销
  2. volatile只能保证共享变量的可见性,不能解决读-改-写等的原子性问题
  3. CAS(Compare and Swap)是JDK提供的非阻塞原子性操作,通过硬件保证了比较-更新操作的原子性

Synchronized

又名监视器锁,释放该锁场景:

  1. 正常退出同步代码块
  2. 抛出异常后
  3. 同步块内调用了该内置锁资源的wait方法时

synchronized内存语义:进入synchronized内使用的共享变量从线程工作内存中清除,这样将会从主内存中去取;退出synchronized会将本地内存修改的共享变量刷新到主内存。

volatile

volatile具有可见性但不具有原子性

CAS

JDK的rt.jar包中的Unsafe类提供了硬件级别的原子性操作,内部提供了一系列原子操作方法,如:

http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/687fd7c7986d/src/share/classes/sun/misc/Unsafe.java

/*
	o:对象内存地址
	offset:对象中变量偏移量
	expected:变量预期值
	update:新更新的值
	方法含义:比较对象o中偏移量为offset的变量值是否与expect相等,相等则使用update值更新,然后返回true,否则返回false
*/
public final native boolean compareAndSwapLong(Object o, long offset,
                                                      long expected,
                                                      long x);
/*
	获取对象o中偏移量为offset的变量对应volatile语义的值
/*
public native long getLongVolatile(Object o, long offset);
//JDK8新增函数
/*
	获取对象obj中偏移量为offset的变量volatile语义的当前值,并设置变量volatile语义的值为update
*/
public final long getAndSetLong(Object obj, long offset, long update) 
/*
	获取对象obj中偏移量为offset的变量volatile语义的当前值,并设置变量值为原始值+addValue
*/
public final long getAndAddLong(Object obj,long offset, long addValue)

Unsafe对象不能通过getUnsafe方法得到

public static Unsafe getUnsafe() {
        Class<?> caller = Reflection.getCallerClass();
    	//如果不是BootStrap类加载器加载则抛出异常
        if (!VM.isSystemDomainLoader(caller.getClassLoader()))
            throw new SecurityException("Unsafe");
        return theUnsafe;
}
//判断paramClassLoader是不是BootStrap类加载器
public static boolean isSystemDomainLoader(ClassLoader paramClassLoader) {
    return paramClassLoader == null;
}

为什么要加这个判断?因为我们在main函数所在的类是AppClassLoader加载的,所以在main函数里面加载Unsafe类时,根据委托机制会委托BootStrap去加载Unsafe类。如果没有这个限制,我们的应用程序可以随意使用Unsafe类,而Unsafe类可以直接操作内存,这是不安全的。

当然如果要使用这个类则需要通过反射来得到,如:

Field field = Unsafe.class.getDeclaredField("theUnsafe");
field.setAccessible(true);
Unsafe unsafe = (Unsafe)field.get(null);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值