最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java中的原子類AtomicInteger使用詳解

 更新時(shí)間:2023年12月08日 10:06:24   作者:努力的小強(qiáng)  
這篇文章主要介紹了Java中的原子類AtomicInteger使用詳解,原子操作是指不會(huì)被線程調(diào)度機(jī)制打斷的操作,這種操作一旦開始,就一直運(yùn)行到結(jié)束,中間不會(huì)有任何線程上下文切換,需要的朋友可以參考下

原子操作

原子操作是指不會(huì)被線程調(diào)度機(jī)制打斷的操作,這種操作一旦開始,就一直運(yùn)行到結(jié)束,中間不會(huì)有任何線程上下文切換。

原子操作可以是一個(gè)步驟,也可以是多個(gè)操作步驟,但是其順序不可以被打亂,也不可以被切割而只執(zhí)行其中的一部分,將整個(gè)操作視作一個(gè)整體是原子性的核心特征。

原子類

在Java中提供了很多原子類,主要把這些原子類分成以下幾大類

在這里插入圖片描述

原子更新基本類型或引用類型

  • AtomicBoolean
    • 原子更新布爾類型,內(nèi)部使用int類型的value存儲(chǔ)1和0表示true和false,底層也是對(duì)int類型的原子操作。
  • AtomicInteger
    • 原子更新int類型。
  • AtomicLong
    • 原子更新long類型。
  • AtomicReference
    • 原子更新引用類型,通過泛型指定要操作的類。
  • AtomicMarkableReference
    • 原子更新引用類型,內(nèi)部使用Pair承載引用對(duì)象及是否被更新過的標(biāo)記,避免了ABA問題。
  • AtomicStampedReference
    • 原子更新引用類型,內(nèi)部使用Pair承載引用對(duì)象及更新的郵戳,避免了ABA問題。

原子更新數(shù)組中的元素

原子更新數(shù)組中的元素,可以更新數(shù)組中指定索引位置的元素。

  • AtomicIntegerArray
    原子更新int數(shù)組中的元素。
  • AtomicLongArray
    原子更新long數(shù)組中的元素。
  • AtomicReferenceArray
    原子更新object數(shù)組中的元素。

原子更新對(duì)象中的字段

原子更新對(duì)象中的字段,可以更新對(duì)象中指定字段名稱的字段。

  • AtomicIntegerFieldUpdater
    原子更新對(duì)象中的int類型字段。
  • AtomicLongFieldUpdater
    原子更新對(duì)象中的long類型字段。
  • AtomicReferenceFieldUpdater
    原子更新對(duì)象中的引用類型字段。

高性能原子類

高性能原子類,是Java8中增加的原子類,它們使用分段的思想,把不同線程hash到不同的段上去更新,最后再把這些段的值相加得到最終的值。

Striped64
下面四個(gè)類的父類。

  • LongAccumulator
    • long類型的聚合器,需要傳入一個(gè)long類型的二元操作,可以用來計(jì)算各種聚合操作,包括加乘等。
  • LongAdder
    • long類型聚合器,LongAccumulator的特例,只能用來計(jì)算加法,且從零開始計(jì)算。
  • DoubleAccumulator
    • double類型的聚合器,需要傳入一個(gè)double類型的二元操作,可以用來計(jì)算各種聚合操作,包括加乘等。
  • DoubleAdder
    • double類型聚合器,DoubleAccumulator的特例,只能用來計(jì)算加法,且從零開始計(jì)算。

AtomicInteger使用

import java.util.concurrent.atomic.AtomicInteger;
public class AtomicIntegerDemo {
    public static void main(String[] args) throws InterruptedException {
        test1();
        test2();
    }
    private static void test1() throws InterruptedException {
        Counter counter = new Counter();
        for (int i = 0; i < 10; i++) {
            new Thread(()->{
                for (int j = 0; j < 1000; j++) {
                    counter.addCount();
                }
            }).start();
        }
        Thread.sleep(1000);
        System.out.println("test1 count = " + counter.getCount());
    }
    private static void test2() throws InterruptedException {
        AtomicInteger count = new AtomicInteger();
        for (int i = 0; i < 10; i++) {
            new Thread(()->{
                for (int j = 0; j < 1000; j++) {
                    count.incrementAndGet();
                }
            }).start();
        }
        Thread.sleep(1000);
        System.out.println("test2 count = " + count.get());
    }
}
public class Counter {
    private volatile static int count = 0;
    public void addCount(){
        count++;
    }
    public int getCount(){
        return count;
    }
}

運(yùn)行以上代碼會(huì)發(fā)現(xiàn),test1的結(jié)果達(dá)不到預(yù)期的10000,而且每次的結(jié)果不可再現(xiàn)。而test2的結(jié)果每次都是10000,是確定的可再現(xiàn)的。

是因?yàn)閠est1中調(diào)用的Counter類的addCount方法,這個(gè)方法不是原子性的。

count++可以分解為以下幾個(gè)原子性的步驟:

1.讀取count的值

2.計(jì)算新值count+1

3.新值寫入count變量

如果步驟1、2、3中有多個(gè)線程并發(fā)執(zhí)行,那么就會(huì)出現(xiàn)兩個(gè)或多個(gè)線程并發(fā)的執(zhí)行+1操作,而我們希望的是每個(gè)線程依次執(zhí)行+1的操作。

AtomicInteger原理

AtomicInteger聲明

public class AtomicInteger extends Number implements java.io.Serializable

Unsafe類的使用

    private static final Unsafe unsafe = Unsafe.getUnsafe();
    private static final long valueOffset;
    static {
        try {
            valueOffset = unsafe.objectFieldOffset
                (AtomicInteger.class.getDeclaredField("value"));
        } catch (Exception ex) { throw new Error(ex); }
    }

AtomicInteger屬性

private volatile int value;

AtomicInteger構(gòu)造器

    public AtomicInteger(int initialValue) {
        value = initialValue;
    }
    public AtomicInteger() {
    }

AtomicInteger自增

    public final int incrementAndGet() {
        return unsafe.getAndAddInt(this, valueOffset, 1) + 1;
    }

調(diào)用Unsafe類的方法

    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;
    }

compareAndSwapInt即CAS方式修改int值:

  1. 調(diào)用unsafe.getAndAddInt方法。
  2. unsafe.getAndAddInt方法通過自旋的方式,每次嘗試通過CAS方式對(duì)原值進(jìn)行累加。如果累加失敗,將進(jìn)入下一次循環(huán)。如果累加成功,則自選結(jié)束。

到此這篇關(guān)于Java中的原子類AtomicInteger使用詳解的文章就介紹到這了,更多相關(guān)Java原子類AtomicInteger內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • SpringCloud修改Feign日志記錄級(jí)別過程淺析

    SpringCloud修改Feign日志記錄級(jí)別過程淺析

    OpenFeign源于Netflix的Feign,是http通信的客戶端。屏蔽了網(wǎng)絡(luò)通信的細(xì)節(jié),直接面向接口的方式開發(fā),讓開發(fā)者感知不到網(wǎng)絡(luò)通信細(xì)節(jié)。所有遠(yuǎn)程調(diào)用,都像調(diào)用本地方法一樣完成
    2023-02-02
  • springboot跨域過濾器fetch react Response to preflight request doesn‘t pass access control check問題

    springboot跨域過濾器fetch react Response to p

    這篇文章主要介紹了springboot跨域過濾器fetch react Response to preflight request doesn‘t pass access control check問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-03-03
  • java分布式流處理組件Producer入門詳解

    java分布式流處理組件Producer入門詳解

    這篇文章主要為大家介紹了java分布式流處理組件Producer入門詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-03-03
  • 如何解決IDEA git拉取代碼后本地代碼莫名消失的問題

    如何解決IDEA git拉取代碼后本地代碼莫名消失的問題

    這篇文章主要介紹了如何解決IDEA git拉取代碼后本地代碼莫名消失的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-07-07
  • Java對(duì)象不使用時(shí)賦值null的意義詳解

    Java對(duì)象不使用時(shí)賦值null的意義詳解

    這篇文章主要介紹了java對(duì)象不再使用時(shí)賦值null的意義,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-03-03
  • List對(duì)象去重和按照某個(gè)字段排序的實(shí)現(xiàn)方法

    List對(duì)象去重和按照某個(gè)字段排序的實(shí)現(xiàn)方法

    下面小編就為大家?guī)硪黄狶ist對(duì)象去重和按照某個(gè)字段排序的實(shí)現(xiàn)方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-05-05
  • 從入門到精通:Java List遍歷修改的完全指南

    從入門到精通:Java List遍歷修改的完全指南

    在Java中,我們經(jīng)常需要遍歷List集合并對(duì)其中的元素進(jìn)行修改,這可以通過使用迭代器或for循環(huán)來實(shí)現(xiàn),需要的朋友可以參考下
    2023-10-10
  • 解決mybatis映射mapper.xml文件不編譯的問題

    解決mybatis映射mapper.xml文件不編譯的問題

    這篇文章主要介紹了解決mybatis映射mapper.xml文件不編譯的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-06-06
  • MyBatis-Plus使用ActiveRecord(AR)實(shí)現(xiàn)CRUD

    MyBatis-Plus使用ActiveRecord(AR)實(shí)現(xiàn)CRUD

    本文將結(jié)合實(shí)例代碼,介紹MyBatis-Plus使用ActiveRecord(AR)實(shí)現(xiàn)CRUD,文中通過示例代碼介紹的非常詳細(xì),需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-07-07
  • java生成隨機(jī)數(shù)(字符串)示例分享

    java生成隨機(jī)數(shù)(字符串)示例分享

    這篇文章主要介紹了java生成隨機(jī)數(shù)(字符串)示例分享,需要的朋友可以參考下
    2014-03-03

最新評(píng)論

大邑县| 津市市| 龙江县| 阳曲县| 宁陕县| 保靖县| 江门市| 石屏县| 白水县| 友谊县| 盘锦市| 和平区| 韶山市| 鸡泽县| 寻甸| 玉龙| 靖西县| 云安县| 招远市| 即墨市| 文成县| 宝应县| 长岭县| 谢通门县| 漳州市| 永川市| 永城市| 华池县| 永丰县| 武山县| 武鸣县| 庄浪县| 许昌市| 绿春县| 行唐县| 芒康县| 沙雅县| 阿巴嘎旗| 济南市| 洛阳市| 营山县|