Java併發工具類——AtomicInteger
阿新 • • 發佈:2018-11-29
基本型別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 }