基本类型int的递增等操作并不是线程安全的,加上synchronized又会影响性能,因此在并发情况下我们应该使用AtomicInteger,下面通过一个例子验证一哈。
public class TestAtomicInteger {
public static void main(String[] args) throws InterruptedException {
ExecutorService executorService = Executors.newCachedThreadPool();
executorService.execute(new AtomicIntegerThread());
executorService.execute(new AtomicIntegerThread());
executorService.execute(new AtomicIntegerThread());
executorService.execute(new AtomicIntegerThread());
executorService.execute(new AtomicIntegerThread());
executorService.execute(new IntegerThread());
executorService.execute(new IntegerThread());
executorService.execute(new IntegerThread());
executorService.execute(new IntegerThread());
executorService.execute(new IntegerThread());
executorService.shutdown();
boolean b = executorService.awaitTermination(5, TimeUnit.SECONDS);
if(b) {
System.out.println("AtomicIntegerThread:" + AtomicIntegerThread.ai.get());
System.out.println("IntegerThread:" + IntegerThread.i);
}else{
System.out.println("time out.");
}
}
}
class AtomicIntegerThread implements Runnable {
static AtomicInteger ai = new AtomicInteger(0);
@Override
public void run() {
for (int m = 0; m < 10000000; m++) {
ai.getAndIncrement();
}
}
}
class IntegerThread implements Runnable {
static int i = 0;
@Override
public void run() {
for (int m = 0; m < 10000000; m++) {
i++;
}
}
}
运行结果如下:
AtomicIntegerThread:50000000
IntegerThread:26507929
AtomicInteger线程安全的运算是基于sun.misc.Unsafe类中的本地方法,关于Unsafe的介绍可以参考sun.misc.Unsafe。
AtomicInteger的常用方法:
//获取当前值
int get();
//设置指定值
void set(int newValue)
//设置指定值并返回原来的值
int getAndSet(int newValue)
// i++
int getAndIncrement()
// ++i
int incrementAndGet()
// i--
int getAndDecrement()
// --i
int decrementAndGet()
//当前值加上delta,返回以前的值
int getAndAdd(int delta)
//当前值加上delta,返回新的值
int addAndGet(int delta)
//如果当前值等于入参expect,则把值设为update,并返回ture,如果不等则返回false
boolean compareAndSet(int expect, int update)
// 1.8新增方法,更新当前值,返回以前的值
int getAndUpdate(IntUnaryOperator updateFunction)
// 1.8新增方法,更新当前值,返回更新后的值
int updateAndGet(IntUnaryOperator updateFunction)
// 1.8新增方法,更新当前值,返回以前的值
int getAndAccumulate(int x,IntBinaryOperator accumulatorFunction)
// 1.8新增方法,更新当前值,返回更新后的值
int accumulateAndGet(int x,IntBinaryOperator accumulatorFunction)
/**
* 演示AtomicInteger中1.8新增方法的使用方法
*/
@Test
public void operatorTest(){
AtomicInteger i = new AtomicInteger(0);
//lambda表达式中参数operand表示AtomicInteger的当前值
int andUpdate = i.getAndUpdate(operand -> ++operand);
System.out.println(andUpdate); //result: 0
System.out.println(i.get()); //result: 1
int i1 = i.updateAndGet(operand -> operand-2 );
System.out.println(i1); //result: -1
System.out.println(i.get()); //result: -1
//lambda表达式中参数left表示AtomicInteger的当前值、right表示前面那个参数5
int andAccumulate = i.getAndAccumulate(5, (left, right) -> left + right);
System.out.println(andAccumulate); //result: -1
System.out.println(i.get()); //result: 4
int i2 = i.accumulateAndGet(4, (left, right) -> left + right);
System.out.println(i2); //result: 8
System.out.println(i.get()); //result: 8
}