public class atomiclong extends number implements java.io.serializable { private static final long serialversionuid = 1927816293512124184l; //1.获取unsafe类实例 private static final unsafe unsafe = unsafe.getunsafe(); //2.存放value的偏移量 private static final long valueoffset; static final boolean vm_supports_long_cas = vmsupportscs8(); //3.用于判断是否支持long类型无锁cas private static native boolean vmsupportscs8(); static { try { //4.获取value在atomiclong中的偏移量 valueoffset = unsafe.objectfieldoffset (atomiclong.class.getdeclaredfield("value")); } catch (exception ex) { throw new error(ex); } } //5.实际变量值 private volatile long value; /** * creates a new atomiclong with the given initial value. * * @param initialvalue the initial value */ public atomiclong(long initialvalue) { value = initialvalue; } ············省略部分代码·············}
上面代码中,代码1处通过unsafe.getunsafe()获取到unsafe类的实例(因为atomiclong类是在rt.jar包下面的,atomiclong类就是通过bootstarp类加载器进行加载的)。代码5处,value被声明为volatile类型,保证内存的可见性。通过代码2,4获取value变量在atomiclong类中的偏移量。
接下来介绍一下atomiclong中的主要函数:
递增和递减代码
//调用unsafe方法,设置value=value+1后,返回原始的值public final long getandincrement() { return unsafe.getandaddlong(this, valueoffset, 1l);}//调用unsafe方法,设置value=value-1后,返回原始的值public final long getanddecrement() { return unsafe.getandaddlong(this, valueoffset, -1l);}//调用unsafe方法,设置value=value+1后,返回递增后的值public final long incrementandget() { return unsafe.getandaddlong(this, valueoffset, 1l) + 1l;}//调用unsafe方法,设置value=value-1后,返回递减后的值public final long decrementandget() { return unsafe.getandaddlong(this, valueoffset, -1l) - 1l;}
上面的四个函数内部都是通过调用unsafe的getandaddlong方法来实现操作,这个函数是个原子性操作,这里第一个参数是atomiclong实例的引用的,第二个参数是value变量在atomiclong的偏移值,第三个参数是要设置的第二个变量的值。
其中getandincrement()方法在jdk7中实现逻辑为:
public final long getandincrement() { while(true) { long current = get(); long next = current + 1; if (compareandset(current, next)) return current; }}
如上代码中,每个线程是先拿到变量的当前值(由于value是volatile变量,所以这是获取的最新值),然后在工作内存中对其进行增1操作,而后使用cas修改变量的值,如果设置失败,则循环继续尝试,直到设置成功。
jdk8中的逻辑为:
public final long getandincrement() { retrturn unsafe.getandaddlong(this, valueoffset, 1l); }
其中jdk8中的unsafe.getandaddlong的代码为:
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;}
从中可以看到,jdk7中的atomiclong中循环逻辑已经被jdk8中的原子操作类unsafe内置了。
boolean compareandset(long expect,long update)
public final boolean compareandset(long expect,long update) { return unsafe.compareandswaplong(this, valueoffset, expect, update);}
函数在内部调用了unsafe.compareandswaplong方法。如果原子变量中的value值等于expect,则使用update值更新该值并返回true,否则返回false。
以上就是java原子操作类源码解析的详细内容。
