java的rt.jar包里面的并发工具类有Atomic开头的原子类
package java.util.concurrent.atomic
此路径下的原子类有天然的并发安全性,我们以AtomicInteger举例说明为什么原子类的操作是线程安全的。
首先我们观察源码:
AtomicInteger类有私有的常量属性 Unsafe类,用Unsafe的CAS操作来保证并发的安全。还有一个volatile 的value;表示真正的值
所以我们看到AtomicInteger的基本操作方法:getAndIncrement()方法,多线程中,能够安全的递增。
如下实例代码,在1000多条线程启动的过程当中,还是能正确的获取数据。
public class NormalTest {
public static void main(String[] args) {
AtomicInteger atomicInteger = new AtomicInteger();
atomicInteger.set(100);
for (int i=0;i<1000;i++) {
createThreadAndUpdateAtomicInteger(atomicInteger);
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
}
System.out.println(atomicInteger.get());
}
private static void createThreadAndUpdateAtomicInteger(AtomicInteger atomicInteger) {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
atomicInteger.getAndIncrement();
}
});
thread.start();
}
}
getAndIncrement()方法如下:
/**
* Atomically increments by one the current value.
*
* @return the previous value
*/
public final int getAndIncrement() {
return unsafe.getAndAddInt(this, valueOffset, 1);
}
只有一句,运用unsafe.getAndAddInt,
具体代码:
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;
}
调用自身的compareAndSwapInt(,,,)方法执行
public final native boolean compareAndSwapInt(Object var1, long var2, int var4, int var5);
最下层调用native方法执行。
需要注意:unsafe的获取方式
// setup to use Unsafe.compareAndSwapInt for updates
private static final Unsafe unsafe = Unsafe.getUnsafe();
@CallerSensitive
public static Unsafe getUnsafe() {
Class var0 = Reflection.getCallerClass();
if (!VM.isSystemDomainLoader(var0.getClassLoader())) {
throw new SecurityException("Unsafe");
} else {
return theUnsafe;
}
}
只能是VM的特殊classLoader才能获取,否则会报错;
所以我们想要获取Unsafe类,需要特殊的反射操作。