Java并发工具类——AtomicInteger

基本类型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
}

猜你喜欢

转载自my.oschina.net/u/2424727/blog/1930345
今日推荐