原子變量提供各類原子操做,多線程場景下操做不須要加鎖,性能很是好java
AtomicInteger ai = new AtomicInteger(10); ExecutorService es = Executors.newCachedThreadPool(); long endTime = System.currentTimeMillis() + 100; for (int i = 0; i < 10; i++) { es.execute(() -> { while (System.currentTimeMillis() < endTime) { System.out.println(ai.incrementAndGet()); System.out.println(ai.addAndGet(1)); } }); } try { es.shutdown(); while (!es.awaitTermination(1, TimeUnit.SECONDS)) { // nothing to do } } catch (InterruptedException e) { e.printStackTrace(); }
get
: 返回當前 int 值incrementAndGet
: 自增,返回自增後的值getAndIncrement
: 自增,發揮自增前的值addAndGet
: 加上一個 int,而且獲取加上以後的值getAndAdd
: 加上一個 int,而且返回加上以前的值compareAndSet
: 當前值與參數相等時,才設置當前值,返回是否設置成功compareAndExchange
: 當前值與參數相等時,才設置當前值,返回老的值AtomicInteger i = new AtomicInteger(10); assertEquals(i.get(), 10); assertEquals(i.incrementAndGet(), 11); assertEquals(i.getAndIncrement(), 11); assertEquals(i.get(), 12); assertEquals(i.addAndGet(10), 22); assertEquals(i.getAndAdd(10), 22); assertEquals(i.get(), 32); assertTrue(i.compareAndSet(32, 10)); assertFalse(i.compareAndSet(32, 10)); assertEquals(i.compareAndExchange(10, 22), 10); assertEquals(i.compareAndExchange(10, 22), 22);
和 AtomicInteger
的接口相似,只是每一個接口都增長一個 index
參數git
AtomicIntegerArray ia = new AtomicIntegerArray(10); for (int i = 0; i < 10; i++) { ia.set(i, i); } assertEquals(ia.get(5), 5); assertEquals(ia.incrementAndGet(5), 6); assertEquals(ia.incrementAndGet(5), 7); assertEquals(ia.addAndGet(5, 10), 17); assertTrue(ia.compareAndSet(5, 17, 15)); assertEquals(ia.compareAndExchange(5, 15, 10), 15); // 返回老值
get
: 獲取當前引用對象getAndSet
: 設置新的引用,並返回老的引用compareAndSet
: 當前值與參數相等時,才設置當前值,返回是否設置成功compareAndExchange
: 當前值與參數相等時,才設置當前值,返回老的值accumulateAndGet
: 用當前值和參數一塊兒執行 BinaryOpterator 的結果設置成當前值,返回新的值getAndAccumulate
: 用當前值和參數一塊兒執行 BinaryOpterator 的結果設置成當前值,返回老的值AtomicReference<Integer> i = new AtomicReference<>(); assertEquals(i.get(), null); assertEquals(i.getAndSet(10), null); assertEquals(i.get(), Integer.valueOf(10)); assertEquals(i.compareAndExchange(10, 11), Integer.valueOf(10)); assertTrue(i.compareAndSet(11, 12)); assertEquals(i.accumulateAndGet(3, (x, y) -> x + y), Integer.valueOf(15)); assertEquals(i.getAndAccumulate(3, (x, y) -> x + y), Integer.valueOf(15));
在 atomic 的基礎上增長一個 stamp 概念,stamp 可理解爲一個版本號,即便兩個相等值相等,還能夠經過版本號來區分github
AtomicStampedReference<Integer> i = new AtomicStampedReference<>(null, 0); assertEquals(i.getReference(), null); assertEquals(i.getStamp(), 0); assertTrue(i.compareAndSet(null, 10, 0, 1)); assertEquals(i.getReference(), Integer.valueOf(10)); assertEquals(i.getStamp(), 1);
LongAccumulator
累加器,內部採用多個 atomic
變量實現,減小因爲多線程競爭帶來的性能開銷,LongAccumulator
經過一個 BinaryOperator
和一個初始值構造而成,而 LongAddr
至關於 new LongAccumulator((x, y) -> x + y, 0)
多線程
{ LongAccumulator i = new LongAccumulator((x, y) -> x + y, 0); i.accumulate(10); i.accumulate(20); assertEquals(i.get(), 30); } { LongAdder j = new LongAdder(); j.add(10); j.add(20); assertEquals(j.sum(), 30); }