Atomic原子包下大概可以分成三类,AtomicInteger、AtomicLong、AtomicBoolean这三个是类似的,这里只写一下AtomicLong相关源码。
Atomic包是基于CAS实现的,CAS需要三个值,分别是要更新的值V,期望值E和新值N。当且仅当V和E相等的时候才可以使用新值对V进行替换,当发生冲突时就循环此过程知道成功为止。CAS是基于UNSAFE这个类实现的,这个类拥有直接修改内存,从硬件层面操纵数据,赋值等操作,还可以修改指针,因此是不安全的类。
这个类本身比较简练,因此代码都放在下面了。其中最重要的地方在于原子性的加法或减法比1.7更加简练,在Unsafe类中进行循环比较。
// 获取Unsafe实例,这个实例只有顶级类加载器加载的类才可以使用
private static final Unsafe unsafe = Unsafe.getUnsafe();
private static final long valueOffset; //地址偏移量
/**
* Records whether the underlying JVM supports lockless
* compareAndSwap for longs. While the Unsafe.compareAndSwapLong
* method works in either case, some constructions should be
* handled at Java level to avoid locking user-visible locks.
*/
static final boolean VM_SUPPORTS_LONG_CAS = VMSupportsCS8();
/**
* Returns whether underlying JVM supports lockless CompareAndSet
* for longs. Called only once and cached in VM_SUPPORTS_LONG_CAS.
*/
private static native boolean VMSupportsCS8();
//获取value这个值在地址中的偏移值。
static {
try {
valueOffset = unsafe.objectFieldOffset
(AtomicLong.class.getDeclaredField("value"));
} catch (Exception ex) { throw new Error(ex); }
}
//记录原子类的当前值,使用volatile保证可见性
private volatile long value;
/**
* 使用初始值作为参数初始化这个类
*
* @param initialValue the initial value
*/
public AtomicLong(long initialValue) {
value = initialValue;
}
/**
* 空的构造函数
*/
public AtomicLong() {
}
/**
* 获取当前类的值
*
* @return the current value
*/
public final long get() {
return value;
}
/**
*给当前类设定新的值
*
* @param newValue the new value
*/
public final void set(long newValue) {
value = newValue;
}
/**
* Eventually sets to the given value.
*
* @param newValue the new value
* @since 1.6
*/
public final void lazySet(long newValue) {
unsafe.putOrderedLong(this, valueOffset, newValue);
}
/**
* 使用UNsafe操作设置新值,并返回旧的值。
*
* @param newValue the new value
* @return the previous value
*/
public final long getAndSet(long newValue) {
return unsafe.getAndSetLong(this, valueOffset, newValue);
}
/**
* 如果当前值等于预期值,那么就原子性的将新值赋给当前值。
*
*/
public final boolean compareAndSet(long expect, long update) {
return unsafe.compareAndSwapLong(this, valueOffset, expect, update);
}
/**
* Atomically sets the value to the given updated value
* if the current value {@code ==} the expected value.
*
* <p><a href="package-summary.html#weakCompareAndSet">May fail
* spuriously and does not provide ordering guarantees</a>, so is
* only rarely an appropriate alternative to {@code compareAndSet}.
*
* @param expect the expected value
* @param update the new value
* @return {@code true} if successful
*/
public final boolean weakCompareAndSet(long expect, long update) {
return unsafe.compareAndSwapLong(this, valueOffset, expect, update);
}
/**
*以原子的方式返回旧值并给值加一
*
* @return the previous value
*/
public final long getAndIncrement() {
return unsafe.getAndAddLong(this, valueOffset, 1L);
}
/**
* 以原子的方式返回旧值并减一
*
* @return the previous value
*/
public final long getAndDecrement() {
return unsafe.getAndAddLong(this, valueOffset, -1L);
}
/**
* 以原子的方式返回旧值并加上一个给定值.
*
* @param delta the value to add
* @return the previous value
*/
public final long getAndAdd(long delta) {
return unsafe.getAndAddLong(this, valueOffset, delta);
}
/**
* 以原子的方式加一并返回
*
* @return the updated value
*/
public final long incrementAndGet() {
return unsafe.getAndAddLong(this, valueOffset, 1L) + 1L;
}
/**
*以原子的形式减一并返回
* @return the updated value
*/
public final long decrementAndGet() {
return unsafe.getAndAddLong(this, valueOffset, -1L) - 1L;
}
/**
* 以原子的形式减去一个给定值并返回当前值,和1.7相比,1.8 的代码更加简练。
*
* @param delta the value to add
* @return the updated value
*/
public final long addAndGet(long delta) {
return unsafe.getAndAddLong(this, valueOffset, delta) + delta;
}
/**
* 返回字符串
*/
public String toString() {
return Long.toString(get());
}
/**
* Returns the value of this {@code AtomicLong} as an {@code int}
* after a narrowing primitive conversion.
* @jls 5.1.3 Narrowing Primitive Conversions
*/
public int intValue() {
return (int)get();
}
/**
* Returns the value of this {@code AtomicLong} as a {@code long}.
*/
public long longValue() {
return get();
}
/**
* Returns the value of this {@code AtomicLong} as a {@code float}
* after a widening primitive conversion.
* @jls 5.1.2 Widening Primitive Conversions
*/
public float floatValue() {
return (float)get();
}
/**
* Returns the value of this {@code AtomicLong} as a {@code double}
* after a widening primitive conversion.
* @jls 5.1.2 Widening Primitive Conversions
*/
public double doubleValue() {
return (double)get();
}
一个简单的实例。
static class Inc implements Runnable{
public AtomicInteger atomicInteger;
Inc(AtomicInteger atomicInteger){
this.atomicInteger=atomicInteger;
}
@Override
public void run(){
for(int i=0;i<100;i++){
atomicInteger.incrementAndGet();
}
}
}
public static void main(String[] args) {
AtomicInteger atomicInteger=new AtomicInteger(0);
ExecutorService executorService=Executors.newFixedThreadPool(10);
for(int i=0;i<10;i++){
executorService.submit(new Thread(new Inc(atomicInteger)));
}
try{//休眠五秒执行完毕
Thread.sleep(1000*5);
}catch (Exception e){
}
System.out.println(atomicInteger.get());}//最后结果是1000