Unsafe补充

/ 默认分类 / 0 条评论 / 985浏览

Unsafe补充

前面在介绍ConcurrentHashMap和LinkedBlockingQueue时,有说一部分Unsafe的api,下面简单总结下一些常用的:

Unsafe中的cas操作:在对象obj中,如果obj所在内存地址偏移量为valueOffset的位置的变量值和expect值相同,那么就使用update替换该偏移量位置的数据返回true,否则就返回false

boolean compareAndSwapLong(Object obj,long valueOffset,long expect, long update)

java中的原子数据类型,比如AtomicInteger等都是基于Unsafe的下列api
下面的api都是对上面cas操作的封装,返回的值是cas修改之前的数值,可以看到这些封装已经实现了循环尝试cas的功能

    public final long getAndAddLong(Object var1, long var2, long var4) {
        long var6;
        do {
            var6 = this.getLongVolatile(var1, var2);
        } while(!this.compareAndSwapLong(var1, var2, var6, var6 + var4));

        return var6;
    }

    public final int getAndSetInt(Object var1, long var2, int var4) {
        int var5;
        do {
            var5 = this.getIntVolatile(var1, var2);
        } while(!this.compareAndSwapInt(var1, var2, var5, var4));

        return var5;
    }

在原子数据类中的增加和减少操作其实也就是封装的Unsafe操作
比如AtomicInteger中的:

    public final int getAndIncrement() {
        return unsafe.getAndAddInt(this, valueOffset, 1);
    }

    /**
     * Atomically decrements by one the current value.
     *
     * @return the previous value
     */
    public final int getAndDecrement() {
        return unsafe.getAndAddInt(this, valueOffset, -1);
    }  
    
    //上面的已经在Unsafe中封装为了循环cas,但是下面的compareAndSet没有循环,所以在很多并发集合框架都写了循环操作  
    public final boolean compareAndSet(int expect, int update) {
        return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
    }

点击下方连接跳转到我之前的并发集合源码分析总结笔记
Java并发编程(一)监视器锁
ConcurrentLinkedQueue与LinkedBlockingQueue