再谈Unsafe

版权声明: https://blog.csdn.net/Dongguabai/article/details/83306627

我们都知道Atomic包里的类基本都是使用Unsafe实现的包装类。而Unsafe类本质就是通过内存偏移量来调整字段的状态,就像setter方法一样,看一个最常见的例子:AtomicInteger:

可以看到调用Unsafe类获取了valueOffset,这个valueOffset就是value这个属性的偏移量。

这里说个题外话,其实在AtomicIntegral中有这样一个set方法:

这个方法明显是线程不安全的。一般如果要保证原子操作肯定是会使用CAS来保证,比如看看这个方法:

重点看看compareAndSwapInt()方法。这个方法有4个参数,第一个参数是当前对象,第二个参数是value的偏移量,第三个参数是期望值,第四个参数是更新值。

比如现在有一个类User:

现在有一个user对象,在堆中的绝对地址为0xxx,对象的每个属性都会有一个偏移量(相对地址),这个偏移量加上0xxx就是绝对地址。所以Unsafe操作的时候传入一个对象,传入一个偏移量。

再比如现在有两个User对象,user1和user2,它们的绝对地址肯定是不一样的,但是它们的偏移量肯定是一样的,因为两个对象的模型,即Class是一样的,但是Object是不一样的,而Java是静态语言,每个属性是固定的,每个属性的偏移量是连续的,但是也不能简单这么说,因为这个也跟属性的类型有关。

在Java 9以后都是使用VarHandle了。就不使用Unsafe了。

猜你喜欢

转载自blog.csdn.net/Dongguabai/article/details/83306627