多執行緒-CAS操作
阿新 • • 發佈:2020-07-21
CAS操作號稱無鎖優化,也叫作自旋;對於一些常見的操作需要加鎖,然後jdk就提供了一些以Atomic開頭的類,這些類內部自動帶了鎖,當然這裡的鎖並非是用synchronized來實現的,而是通過CAS操作來實現的;
一、下面是AtomicInteger 的使用:
package com.designmodal.design.juc01; import java.util.ArrayList; import java.util.List; import java.util.concurrent.atomic.AtomicInteger; /** * @author D-L * @Classname T03_AtomicInteger * @Version 1.0 * @Description 使用 AtomicInteger 類解決常見的 多執行緒count++ * 其內部使用了CAS操作來保證原子性 但是不能保證多個方法連續呼叫都是原子性 * @Date 2020/7/21 0:35*/ public class T03_AtomicInteger { //使用AtomicInteger類 AtomicInteger count = new AtomicInteger(0); public void m(){ for (int i = 0; i < 10000; i++) { //等同於 在 count++ 上加鎖 count.incrementAndGet(); } } public static void main(String[] args) { T03_AtomicInteger t= new T03_AtomicInteger(); List<Thread> threads = new ArrayList<>(); for (int i = 0; i < 10; i++) { threads.add(new Thread(t::m , "Thread" + i)); } threads.forEach((o) -> o.start()); threads.forEach(o ->{ try { o.join(); }catch (InterruptedException e) { e.printStackTrace(); } }); System.out.println(t.count); } }
二、當然達到使用的級別很簡單,看一下API就好了,通過上面的小程式,下面主要來聊一聊原理:
1、首先小程式中定義了一個AtomicInteger 型別的變數count;
AtomicInteger count = new AtomicInteger(0);
public void add(){
count.incrementAndGet();
}
2、呼叫了AtomicInteger類中incrementAndGet();
/** * Atomically increments by one the current value. * * @return the updated value */ public final int incrementAndGet() { return unsafe.getAndAddInt(this, valueOffset, 1) + 1; }
3、呼叫unsafe類中的getAndAddInt(Object var1, long var2, int var4)方法;
public native int getIntVolatile(Object var1, long var2); public final native boolean compareAndSwapInt(Object var1, long var2, int var4, int var5); public final int getAndAddInt(Object var1, long var2, int var4) { int var5; do { var5 = this.getIntVolatile(var1, var2); } while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4)); return var5; }