AtomicInteger是一个提供原子操作处理的类,主要用于高并发环境下进行高效的程序处理,所在的包路径为:java.util.concurrent.atomic。
首先,要说的是,在Java语言中,对数值进行相加或相减的时候,马上会想到用++i 或者 ++、–i 或者 –,事实上这些操作都不是线程安全的,非要使用的话,不可避免地会用到同步关键字synchronize来修饰。
我们来看看对比:
public class MyTest {
private int value;
public MyTest(int value) {
this.value = value;
}
public synchronized int increase() {
return value++;
}
public static void main(String[] args) {
long start = System.currentTimeMillis();
MyTest myTest = new MyTest(0);
for (int i = 0; i < 10000000; i++) {
myTest.increase();
}
long end = System.currentTimeMillis();
System.out.println("执行完成用时:" + (end - start));
//
long start1 = System.currentTimeMillis();
AtomicInteger atomicInteger = new AtomicInteger(0);
for (int i = 0; i < 10000000; i++) {
atomicInteger.incrementAndGet();
}
long end1 = System.currentTimeMillis();
System.out.println("执行完成用时:" + (end1 - start1));
}
}
执行的结果:
执行完成用时:241
执行完成用时:112
其次,我们来看看源代码里提供的方法有哪些:
1、获得当前的最新值
/**
* Gets the current value.
*
* @return the current value
*/
public final int get() {
return value;
}
2、获得当前的值,并赋予新的一个值
/**
* Atomically sets to the given value and returns the old value.
*
* @param newValue the new value
* @return the previous value
*/
public final int getAndSet(int newValue) {
for (;;) {
int current = get();
if (compareAndSet(current, newValue))
return current;
}
}
3、取得当前的值,并自增
/**
* Atomically increments by one the current value.
*
* @return the previous value
*/
public final int getAndIncrement() {
for (;;) {
int current = get();
int next = current + 1;
if (compareAndSet(current, next))
return current;
}
}
4、取得当前的值,并自减
/**
* Atomically decrements by one the current value.
*
* @return the previous value
*/
public final int getAndDecrement() {
for (;;) {
int current = get();
int next = current - 1;
if (compareAndSet(current, next))
return current;
}
}
5、获得当前的值,并加上预期的值
/**
* Atomically adds the given value to the current value.
*
* @param delta the value to add
* @return the previous value
*/
public final int getAndAdd(int delta) {
for (;;) {
int current = get();
int next = current + delta;
if (compareAndSet(current, next))
return current;
}
}
观察我们得知,以上其中几个方法都调用了这个方法:
/**
* Atomically sets the value to the given updated value
* if the current value {@code ==} the expected value.
*
* @param expect the expected value
* @param update the new value
* @return true if successful. False return indicates that
* the actual value was not equal to the expected value.
*/
public final boolean compareAndSet(int expect, int update) {
return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}
/**
* Atomically sets the value to the given updated value
* if the current value {@code ==} the expected value.
*
* <p>May <a href="package-summary.html#Spurious">fail spuriously</a>
* and does not provide ordering guarantees, so is only rarely an
* appropriate alternative to {@code compareAndSet}.
*
* @param expect the expected value
* @param update the new value
* @return true if successful.
*/
public final boolean weakCompareAndSet(int expect, int update) {
return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}
表面看着方法名不同,实际上调用的方法还是一样的,
//使用unsafe的native方法,实现高效的硬件级别CAS
unsafe.compareAndSwapInt(this, valueOffset, expect, update);
关键域有:
// setup to use Unsafe.compareAndSwapInt for updates
private static final Unsafe unsafe = Unsafe.getUnsafe();
private static final long valueOffset;
unsafe其实就是java语言提供的获得对象内存地址的访问类,它的实质作用是在更新操作时提供“比较并替换更新”的作用;valueOffset则是用来记录value值本身在内存中的偏移地址,主要是为了在更新操作时候,方便地在内存中找到value的位置,然后进行比较。
注意:value是用来存储整数的时间变量,这里被声明为volatile,就是为了保证在更新操作时,当前线程可以拿到value最新的值(并发环境下,value可能已经被其他线程更新了)。
网上的参考资料:
1)Java 理论与实践: 流行的原子
http://www.ibm.com/developerworks/cn/java/j-jtp11234/
2)
http://stackoverflow.com/questions/2443239/how-can-weakcompareandset-fail-spuriously-if-it-is-implemented-exactly-like-comp