Unsafe类解析
Unsafe类简介
Unsafe类位于sun.misc包下,Unsafe类可以直接操作内存,并提供了无锁并发的实现方式CAS(compare and swap),juc包下的大部分工具都是基于该类实现,所以要想深入理解juc必须先要了解Unsafe。然而Java官方并不建议使用该类,所以我们无法在程序进行调用,需要通过反射机制进行调用。
Unsafe类使用
查看源码,会发现该类的构造方法是private的,这意味这我们无法通过直接创建该类的示例。但是其内部有这样一个类变量,并且提供了访问方法
1 |
|
我们先尝试直接调用getUnsafe方法
1 |
|
结果发现程序报错,java不允许我们直接调用该类,所以这时候需要采用特殊手段,即通过反射方式获取theUsafe类变量。
1 |
|
常用方法
CAS
该类最重要的方法就是CAS相关方法,通过这些方法可以实现无锁并发。
锁可以按照策略分为乐观锁和悲观锁,悲观锁认为每次访问共享资源都会发生冲突,所以需要对每一次数据访问加锁。而乐观锁认为共享资源的访问不会总是发生冲突,没有冲突的时候线程继续执行,一旦发生冲突,通过CAS技术保证线程安全。
CAS的核心思想是维护三个值,即待更新变量、预期值、新值,如果待更新变量的值等于预期值,则将其更新为新值,否则说明该值已经被其他线程修改,此时不执行更新操作。
Unsafe中,比较常用的cas方法有
1 | //var1是待更新对象,var2是对象内存的偏移量,通过偏移量获取该字段的值,var4是预期值,var5是要设置的值 |
1.8中还新增了下面几个方法
1 | //给定对象和字段偏移量,将其增加var4,这里需要注意,是先get再add,返回值是get的值,不返回add后的值 |
类、对象、变量操作方法
上述方法中都用到了偏移量,那么偏移量是如何获取的?Unsafe类中提供了很多关于对象、对象、变量的操作方法,可以让我们方便地获取目标字段的偏移量。
1 | //获取静态属性偏移量,用于类中静态属性的读写 |
内存管理
1 |
|
创建对象
Unsafe还提供了新建对象的方法,需要注意的是该方法并不会调用对象的构造方法。所以创建对象的方式一共有5种,并不是流传最广的4种。
1 |
|
例子
1 | public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, InstantiationException { |
1 | public class User { |