JUC之AtomicInteger
我们知道在线程中++i和i--是线程不安全的,我们首先想到的可能就是synchronized关键字。
低并发情况下:使用AtomicInteger,因为其是基于乐观锁,并发低。
高并发情况下:使用synchronized,如果使用AtomicInteger,程序消耗资源会增大,甚至很可能失败,因为:
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;
}
public class TestAtomicDemo {
public static void main(String[] args) {
AtomicDemo ad = new AtomicDemo();
for (int i = 0; i < 5; i++) {
//开启线程
new Thread(ad).start();
}
}
}
//写一个类实现Runable接口
class AtomicDemo implements Runnable {
/*
* AtomicInteger,一个提供原子操作的Integer的类。在Java语言中,
* ++i和i++操作并不是线程安全的,在使用的时候,不可避免的会用到synchronized关键字。
* 而AtomicInteger则通过一种线程安全的加减操作接口。
* 底层是volatile关键字
* */
private AtomicInteger serialNumber = new AtomicInteger();
/*源码解析
* public class AtomicInteger extends Number implements java.io.Serializable {
* 实现序列化接口
private static final long serialVersionUID = 6214790243416807050L;
// setup to use Unsafe.compareAndSwapInt for updates (使用CAS算法)
private static final Unsafe unsafe = Unsafe.getUnsafe();
private static final long valueOffset;
static {
try {
valueOffset = unsafe.objectFieldOffset
(AtomicInteger.class.getDeclaredField("value"));
} catch (Exception ex) { throw new Error(ex); }
}
*
* volatile修饰变量
* private volatile int value;
* */
@Override
public void run() {
System.out.println(getNumber());
System.out.println("-------");
}
public int getNumber() {
//自增
//return serialNumber.getAndIncrement();
return serialNumber.getAndDecrement();//自减
}
}