java原子变量

Java原子变量

原子变量是Java的concurrent包当中的提供的并发工具,其提供了锁(synchronized关键字等)之外的在CPU指令一级进行同步的方法。

CAS(compare and set)

最常见的在多线程的程序当中进行同步的方法就是加锁(Java中对于较简单的就是synchronized关键字),但是锁有很多坏处,其中的最显著的就是效率问题,当锁过多的时候,线程之间的竞争会很严重,效率会严重下降。

CAS相比较而言,并不限制多个线程对资源的同时访问,而是在对资源进行更新的时候将某个线程得到的原值A和内存中的值进行比较,如果A和内存当中的值相同,那么说明原值还没有被其他线程修改过,那么这个线程的更新就是可靠的,可以把值写回内存。如果说A与内存当中的值不同,那么就已经说明原值已被其他线程更新,这是就需要重新取值进行计算。

实现

在实现当中,作者使用了unsafe类,一般来讲,unsafe类提供了使Java虚拟机直接操作内存的方法。以AtomicInteger为例,对其更新操作会由unsafe类直接对内存进行操作,:

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

上面的valueOffset是原子类当中的变量,记录了变量在内存的偏移量。Unsafe类当中的getAndAddInt方法会首先取得内存当中的原值,this.compareSwqpInt是本地方法,其实现直接利用了CPU的CAS指令,会比较内存值和object值,在比较相同之后才会进行更新,否则会一直循环。

    //Unsafe.java
    public final int getAndAddInt(Object var1, long var2, int var4) {
        int var5;
        do {
            var5 = this.getIntVolatile(var1, var2);
        } while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));

        return var5;
    }