1. 程式人生 > >Java併發工具類——AtomicInteger

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
}