Java --Atomic(原子)

原子性操作,在多線程下 該變量的操作是原子性的,不需要添加:synchronized

例子

啟用100個線程,每個線程做+1的操作,最終的結(jié)果應(yīng)該會得到 100才對

public static void main(String args[]) throws InterruptedException {
        //使用線程池
        ExecutorService service = Executors.newCachedThreadPool();
        TestCount testCount=new TestCount();
        long time=System.currentTimeMillis();
        //100個線程對count+1
        for(int i=1;i<=100;i++){
           service.execute(()->testCount.increase());
        }
        // 等待上述的線程執(zhí)行完
        service.shutdown();
        service.awaitTermination(1, TimeUnit.DAYS);
        System.out.println("計算結(jié)果:"+testCount.getCount());
    }
    
     //類
    public static final class TestCount{
        private Integer count=0;

        public Integer getCount() {
            return count;
        }

        public void setCount(Integer count) {
            this.count = count;
        }
        
        public void increase(){
            count++;
        }
    }

最終的記結(jié)果會出現(xiàn) 97 96 .等的情況,就是說count 這個共享變量是線程不安全的呀,線程都共享這個變量


image.png

使用 AtomicInteger 修改count 變量

    public static final class TestCount{
        private AtomicInteger count = new AtomicInteger(0);
        public Integer getCount() {
            return count.get();
        }
        public void increase(){
            count.incrementAndGet();
        }
    }

不管執(zhí)行多少次都是100 結(jié)果正確


image.png

Atomic 的類

image.png

基本類型:
AtomicBoolean:布爾型
AtomicInteger:整型
AtomicLong:長整型

數(shù)組:
AtomicIntegerArray:數(shù)組里的整型
AtomicLongArray:數(shù)組里的長整型
AtomicReferenceArray:數(shù)組里的引用類型

引用類型:
AtomicReference:引用類型
AtomicStampedReference:帶有版本號的引用類型
AtomicMarkableReference:帶有標(biāo)記位的引用類型

對象的屬性:
AtomicIntegerFieldUpdater:對象的屬性是整型
AtomicLongFieldUpdater:對象的屬性是長整型
AtomicReferenceFieldUpdater:對象的屬性是引用類型
JDK8新增DoubleAccumulator、LongAccumulator、DoubleAdder、LongAdder
是對AtomicLong等類的改進(jìn)。比如LongAccumulator與LongAdder在高并發(fā)環(huán)境下比AtomicLong更高效。

AtomicReferenceFieldUpdater、AtomicIntegerFieldUpdater和AtomicLongFieldUpdater是基于反射的實用工具,可以提供對關(guān)聯(lián)字段類型的訪問。例如AtomicIntegerFieldUpdater可以對指定類的指定volatile int字段進(jìn)行原子更新。

原子類可以替換鎖嗎?
原子類不是鎖的常規(guī)替換方法。僅當(dāng)對象的重要更新限定于單個變量時才應(yīng)用它。

原子類和java.lang.Integer等類的區(qū)別
原子類不提供諸如hashCode和compareTo之類的方法。因為原子變量是可變的。

:LongAdder中會維護一組(一個或多個)變量,這些變量加起來就是要以原子方式更新的long型變量。當(dāng)更新方法add(long)在線程間競爭時,該組變量可以動態(tài)增長以減緩競爭。方法sum()返回當(dāng)前在維持總和的變量上的總和。與AtomicLong相比,LongAdder更多地用于收集統(tǒng)計數(shù)據(jù),而不是細(xì)粒度的同步控制。在低并發(fā)環(huán)境下,兩者性能很相似。但在高并發(fā)環(huán)境下,LongAdder有著明顯更高的吞吐量,但是有著更高的空間復(fù)雜度。

import java.util.concurrent.atomic.AtomicLong;

class Counter {
    private static AtomicLong counter = new AtomicLong(0);

    public static long addOne() {
        return counter.incrementAndGet();
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 什么是原子類 原子是不可分割的最小單位,故原子類可以認(rèn)為其操作都是不可分割 一個操作時不可中斷的,即便是在多線程的...
    小波同學(xué)閱讀 891評論 0 1
  • 前言 只有光頭才能變強 之前已經(jīng)寫過多線程相關(guān)的文章了,有興趣的同學(xué)可以去了解一下: https://github...
    Java3y閱讀 1,681評論 1 24
  • java atomic 原子變量提供各種原子操作,多線程場景下操作不需要加鎖,性能非常好 簡例 AtomicInt...
    hatlonely閱讀 569評論 0 0
  • 線程安全性 線程安全性定義: 當(dāng)多個線程訪問某個類時,不管運行時環(huán)境采用何種調(diào)度方式或者這些進(jìn)程將如何交替執(zhí)行,并...
    端碗吹水閱讀 166評論 0 0
  • 第一種(不推薦,功力不夠,用錯會達(dá)不到同步效果)synchronized正確用法 第二種 第三種(優(yōu)先選擇) 參考...
    else05閱讀 9,538評論 0 2

友情鏈接更多精彩內(nèi)容