easy-base-concurrent | 執行緒安全-原子性
阿新 • • 發佈:2018-12-12
Atomic包
- AtomicXXX:CAS、unsafe.compareAndSwapInt
@ThreadSafe
@Slf4j
public class SafeCountAtomic {
public static int clientTotal = 5000;
public static int threadTotal = 200;
public static AtomicInteger count = new AtomicInteger(0);
public static void main(String[] args) throws InterruptedException {
ExecutorService executorService = Executors.newCachedThreadPool();
final Semaphore semaphore = new Semaphore(threadTotal);
final CountDownLatch countDownLatch = new CountDownLatch(clientTotal);
for (int i = 0; i < clientTotal; i++) {
executorService.execute (() -> {
try {
semaphore.acquire();
add();
semaphore.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
countDownLatch.countDown();
} );
}
countDownLatch.await();
executorService.shutdown();
log.info("count:{}", count.get()); // 5000
}
private static void add() {
count.incrementAndGet();
// count.getAndIncrement();
}
}
原始碼分析 AtomicInteger.class
public final int incrementAndGet() {
return unsafe.getAndAddInt(this, valueOffset, 1) + 1;
}
Unsafe.class
// 傳入物件,
public final int getAndAddInt(Object var1, long var2, int var4) {
int var5;
do {
// 從主記憶體中獲取到值
var5 = this.getIntVolatile(var1, var2);
// 將var1物件,工作記憶體中的值(var2)和主記憶體中的值(var5)比較,
// 如果相等,則將該值設定為( var5 + var4),
// 如果不相等,迴圈直到相等。
} while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));
// 返回主記憶體中的值
return var5;
}
// JVM底層方法
public final native boolean compareAndSwapInt(Object var1, long var2, int var4, int var5);