扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
这篇文章主要介绍Java并发编程之CAS的案例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!
为婺城等地区用户提供了全套网页设计制作服务,及婺城网站建设行业解决方案。主营业务为成都网站建设、网站制作、婺城网站设计,以传统方式定制建设网站,并提供域名空间备案等一条龙服务,秉承以专业、用心的态度为用户提供真诚的服务。我们深信只要达到每一位用户的要求,就会得到认可,从而选择与我们长期合作。这样,我们也可以走得更远!在Java并发编程的世界里,synchronized 和 Lock 是控制多线程并发环境下对共享资源同步访问的两大手段。其中 Lock 是 JDK 层面的锁机制,是轻量级锁,底层使用大量的自旋+CAS操作实现的。
那什么是CAS呢?CAS,compare and swap,即比较并交换,什么是比较并交换呢?在Lock锁的理念中,采用的是一种乐观锁的形式,即多线程去修改共享资源时,不是在修改之前就加锁,而是乐观的认为没有别的线程和自己争锁,就是通过CAS的理念去保障共享资源的安全性的。CAS的基本思想是,拿变量的原值和内存中的值进行比较,如果相同,则原值没有被修改过,那么就将原值修改为新值,这两步是原子的,能够保证同一时间只有一个线程修改成功。这就是CAS的理念。
Java中要想使用CAS原子的修改某值,怎么做呢?幸运的是Java提供了这样的API,就是在sun.misc.Unsafe.java类中。Unsafe,中文名不安全的,也被称为魔术类,魔法类。
Unsafe类介绍
Unsafe类使Java拥有了像C语言的指针一样操作内存空间的能力,一旦能够直接操作内存,这也就意味着
(1)不受JVM管理,意思就是使用Unsafe操作内存无法被JVM GC,需要我们手动GC,稍有不慎就会出现内存泄漏。
(2)Unsafe的不少方法中必须提供原始地址(内存地址)和被替换对象的地址,并且偏移量要自己计算(其提供的有计算偏移量的方法),所以一旦出现问题就是JVM崩溃级别的异常,会导致整个JVM实例崩溃,表现为应用程序直接crash掉。
(3)直接操作内存,所以速度更快,在高并发的条件之下能够很好地提高效率。
因此,从上面三个角度来看,虽然在一定程度上提升了效率但是也带来了指针的不安全性。这也是它被取名为Unsafe的原因吧。
下面我们深入到源码中看看,提供了什么方法直接操作内存。
打开Unsafe这个类,我们会发现里面有大量的被native关键字修饰的方法,这意味着这些方法是C语言提供的实现,底层调的是C语言的库函数,我们无法直接看到他的源码实现,需要去从OpenJDK去看了。另外还有一些基于native方法封装的其他方法,整个Unsafe中的方法大致可以归结为以下几类:
(1)初始化操作
(2)操作对象属性
(3)操作数组元素
(4)线程挂起和恢复
(5)CAS机制
CAS的使用
如果你学过java并发编程的话,稍微阅读过JUC并发包里面的源码的话,对这个Unsafe类一定不陌生,因为整个java并发包底层实现的核心就是靠它。JUC并发包中主要使用它提供的CAS(compare and swap,比较并交换)操作,原子的修改锁的状态和一些队列元素。
没看过JUC源码的读者也不用担心,今天我们就是简单介绍Unsafe类中的CAS操作,那么我们接下来就会通过一个简单的例子来看看Unsafe的CAS是怎么使用的。
首先,使用这个类我们第一个要做的事情就是拿到这个类的实例,下面我们自定义了一个Util类用来获取Unsafe的实例
import sun.misc.Unsafe; import java.lang.reflect.Field; public class UnsafeUtil { public static Unsafe reflectGetUnsafe() { try { Field field = Unsafe.class.getDeclaredField("theUnsafe"); field.setAccessible(true); return (Unsafe) field.get(null); } catch (Exception e) { e.printStackTrace(); } return null; } }
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流