国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

JUC并發(fā)編程之原子類

這篇具有很好參考價值的文章主要介紹了JUC并發(fā)編程之原子類。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報違法"按鈕提交疑問。

目錄

1. 什么是原子操作

1.1?原子類的作用

1.2?原子類的常見操作

原子類的使用注意事項


并發(fā)編程是現(xiàn)代計算機(jī)應(yīng)用中不可或缺的一部分,而在并發(fā)編程中,處理共享資源的并發(fā)訪問是一個重要的問題。為了避免多線程訪問共享資源時出現(xiàn)競態(tài)條件(Race Condition)等問題,Java提供了一組原子類(Atomic Classes)來支持線程安全的操作。

1. 什么是原子操作

在并發(fā)編程中,原子操作是不可被中斷的一個或一系列操作,要么全部執(zhí)行成功,要么全部不執(zhí)行,不會出現(xiàn)部分執(zhí)行的情況。原子操作能夠保證在多線程環(huán)境下,對共享資源的操作不會相互干擾,從而確保數(shù)據(jù)的一致性和可靠性。

1.1?原子類的作用

Java提供了一組原子類,位于java.util.concurrent.atomic包中,用于在多線程環(huán)境下進(jìn)行原子操作。這些原子類利用底層的硬件支持或自旋鎖等機(jī)制來實現(xiàn)線程安全的操作,避免了顯式地使用synchronized關(guān)鍵字等鎖機(jī)制,從而提高了并發(fā)性能。

原子類的作用主要有以下幾點(diǎn):

  1. 提供線程安全的操作: 原子類提供了一些常見的操作,如讀取、更新、比較交換等,這些操作在執(zhí)行時不會受到其他線程的干擾,從而確保數(shù)據(jù)的一致性。

  2. 避免競態(tài)條件: 使用原子類可以有效地避免多線程環(huán)境下的競態(tài)條件問題,例如多個線程同時對同一個變量進(jìn)行操作,可能導(dǎo)致不可預(yù)測的結(jié)果。

  3. 提高性能: 原子類在實現(xiàn)上利用了一些底層的技術(shù),避免了傳統(tǒng)鎖機(jī)制的開銷,因此在某些情況下可以提供更好的性能。

1.2?原子類的常見操作

1. AtomicBoolean

AtomicBoolean類提供了原子的布爾值操作,支持原子的設(shè)置和獲取操作。

AtomicBoolean atomicBoolean = new AtomicBoolean(true);

boolean currentValue = atomicBoolean.get(); // 獲取當(dāng)前值
boolean updatedValue = atomicBoolean.compareAndSet(true, false); // 如果當(dāng)前值為true,則設(shè)置為false

?

2. AtomicInteger 和 AtomicLong

AtomicIntegerAtomicLong分別提供了原子的整數(shù)和長整數(shù)操作,包括增加、減少、獲取等操作。

AtomicInteger atomicInt = new AtomicInteger(0);

int currentValue = atomicInt.get(); // 獲取當(dāng)前值
int newValue = atomicInt.incrementAndGet(); // 增加1并返回新值
int updatedValue = atomicInt.addAndGet(5); // 增加5并返回新值

3. AtomicReference

AtomicReference允許在原子級別上操作引用類型的數(shù)據(jù)。它提供了get、setcompareAndSet等方法。

AtomicReference<String> atomicRef = new AtomicReference<>("initial value");

String currentValue = atomicRef.get(); // 獲取當(dāng)前值
boolean updated = atomicRef.compareAndSet("initial value", "new value"); // 如果當(dāng)前值為"initial value",則設(shè)置為"new value"

?

4. AtomicStampedReference

AtomicStampedReference是對AtomicReference的擴(kuò)展,它還包含一個時間戳,用于解決ABA問題(即一個值被修改為另一個值,然后又被修改回原來的值,但是在這之間可能發(fā)生了其他的變化)。

AtomicStampedReference<String> atomicStampedRef = new AtomicStampedReference<>("initial value", 0);

int currentStamp = atomicStampedRef.getStamp(); // 獲取當(dāng)前時間戳
String currentValue = atomicStampedRef.getReference(); // 獲取當(dāng)前值
boolean updated = atomicStampedRef.compareAndSet("initial value", "new value", 0, 1); // 如果當(dāng)前值為"initial value"且時間戳為0,則設(shè)置為"new value"和時間戳為1

5. AtomicArray

AtomicArray類允許在原子級別上操作數(shù)組元素,提供了針對數(shù)組元素的原子更新操作。

AtomicIntegerArray atomicIntArray = new AtomicIntegerArray(5);

int currentValue = atomicIntArray.get(2); // 獲取索引為2的元素值
atomicIntArray.set(3, 10); // 設(shè)置索引為3的元素值為10
int updatedValue = atomicIntArray.getAndAdd(1, 5); // 增加索引為1的元素值,并返回舊值

6. AtomicReferenceFieldUpdater

AtomicReferenceFieldUpdater是Java中的一個工具類,用于進(jìn)行原子更新類的引用類型字段的操作。它允許您在不使用鎖的情況下對指定的引用字段進(jìn)行原子操作,類似于AtomicFieldUpdater,但專門用于引用類型的字段。AtomicReferenceFieldUpdater主要用于確保在多線程環(huán)境下對引用字段的操作是線程安全的,并且可以提供更好的性能。

AtomicReferenceFieldUpdater適用于以下場景:

  1. 當(dāng)您需要在不使用鎖的情況下對特定類的引用字段進(jìn)行原子更新時。

  2. 當(dāng)引用字段的訪問修飾符是volatile,以確保多線程之間的可見性。

  3. 當(dāng)您希望在多個實例之間共享原子更新引用字段的功能,而不是整個對象。

要使用AtomicReferenceFieldUpdater,首先需要創(chuàng)建一個AtomicReferenceFieldUpdater的實例。這可以通過調(diào)用AtomicReferenceFieldUpdater.newUpdater(Class<T> tclass, Class<V> vclass, String fieldName)方法來實現(xiàn),其中:

  • tclass是包含字段的類的Class對象。
  • vclass是字段的引用類型的Class對象。
  • fieldName是要進(jìn)行原子操作的引用字段的名稱。

以下是一個示例代碼片段,演示如何創(chuàng)建和使用AtomicReferenceFieldUpdater實例:

public class AtomicReferenceFieldUpdaterExample {
    public static class Student {
        public volatile String name;
    }

    public static void main(String[] args) {
        Student student = new Student();
        AtomicReferenceFieldUpdater<Student, String> updater =
                AtomicReferenceFieldUpdater.newUpdater(Student.class, String.class, "name");

        updater.set(student, "Alice"); // 原子地設(shè)置name字段為"Alice"
        String updatedName = updater.get(student); // 原子地獲取name字段的值
        System.out.println("Updated Name: " + updatedName);
    }
}

AtomicReferenceFieldUpdater提供了一系列的原子操作方法,用于對指定引用字段進(jìn)行原子更新。這些方法包括:

  • boolean compareAndSet(T obj, V expect, V update):如果當(dāng)前值等于expect,則將字段更新為update,返回是否更新成功。

  • V getAndSet(T obj, V newValue):將字段更新為newValue,并返回之前的值。

  • V getAndUpdate(T obj, UnaryOperator<V> updateFunction):使用給定的更新函數(shù)更新字段,并返回更新前的值。

  • V updateAndGet(T obj, UnaryOperator<V> updateFunction):使用給定的更新函數(shù)更新字段,并返回更新后的值。

  • V getAndAccumulate(T obj, V x, BinaryOperator<V> accumulatorFunction):使用給定的累加函數(shù)將字段與x進(jìn)行累加操作,并返回更新前的值。

  • V accumulateAndGet(T obj, V x, BinaryOperator<V> accumulatorFunction):使用給定的累加函數(shù)將字段與x進(jìn)行累加操作,并返回更新后的值。

7.?LongAdder

LongAdder是Java并發(fā)包中提供的一種用于高并發(fā)場景下對long類型進(jìn)行累加操作的工具類。與傳統(tǒng)的AtomicLong相比,LongAdder在高并發(fā)情況下通常能夠提供更好的性能,因為它采用了一種分段的方式來減少競爭。LongAdder的引入主要是為了應(yīng)對高并發(fā)累加操作的性能瓶頸,特別是在多核處理器上。

LongAdder在高并發(fā)場景下的主要優(yōu)勢在于分段累加,以及對熱點(diǎn)數(shù)據(jù)的分離處理。傳統(tǒng)的AtomicLong在高并發(fā)情況下可能會因為多線程之間的競爭而導(dǎo)致性能下降,而LongAdder通過將累加操作分成多個段,每個段維護(hù)一個計數(shù)器,從而減少了競爭。

另外,LongAdder還引入了一種稱為“分離器”(Cell)的機(jī)制。分離器是計數(shù)器的基本單元,每個線程在累加時會選擇一個分離器進(jìn)行操作,這避免了多線程頻繁地競爭同一個計數(shù)器,從而減少了競爭帶來的開銷。

要使用LongAdder,只需要簡單地創(chuàng)建一個LongAdder的實例即可:

LongAdder longAdder = new LongAdder();

?

LongAdder提供了一些常用的方法來進(jìn)行累加操作:

  • void add(long x):將指定的值添加到計數(shù)器中。

  • void increment():將計數(shù)器增加1。

  • void decrement():將計數(shù)器減少1。

  • long sum():返回當(dāng)前計數(shù)器的總和。

  • void reset():將計數(shù)器重置為0。

  • void addThenReset(long x):將指定的值添加到計數(shù)器中,然后將計數(shù)器重置為0。

原子類的使用注意事項

  1. 性能考慮: 雖然原子類可以提供一定程度的性能優(yōu)勢,但并不是適用于所有情況。在高并發(fā)場景下,考慮使用原子類;而在低并發(fā)、性能要求不高的情況下,可能傳統(tǒng)的同步機(jī)制更加合適。

  2. CAS操作的限制: 原子類的底層實現(xiàn)主要依賴于CAS(Compare-And-Swap)操作,這是一種樂觀鎖機(jī)制。然而,CAS操作可能會在競爭激烈的情況下導(dǎo)致自旋等待,影響性能。

  3. ABA問題: 原子類的CAS操作可能存在ABA問題,即一個值從A變?yōu)锽,然后又從B變?yōu)锳,這時CAS操作可能會錯誤地認(rèn)為值沒有發(fā)生變化。可以使用AtomicStampedReference來解決此問題。

  4. 復(fù)合操作的原子性: 原子類的單個操作是原子的,但多個操作的組合并不一定是原子的。例如,AtomicIntegerincrementAndGet操作是原子的,但在使用時仍然需要考慮復(fù)合操作的原子性。

  5. 適用范圍: 原子類適用于簡單的原子操作,但并不適用于復(fù)雜的業(yè)務(wù)邏輯。對于復(fù)雜的操作,可能需要使用鎖等更高級的同步機(jī)制來確保線程安全。文章來源地址http://www.zghlxwxcb.cn/news/detail-641124.html

到了這里,關(guān)于JUC并發(fā)編程之原子類的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點(diǎn)擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 《C++并發(fā)編程實戰(zhàn)》讀書筆記(4):原子變量

    標(biāo)準(zhǔn)原子類型的定義位于頭文件 atomic 內(nèi)。原子操作的關(guān)鍵用途是取代需要互斥的同步方式,但假設(shè)原子操作本身也在內(nèi)部使用了互斥,就很可能無法達(dá)到期望的性能提升。有三種方法來判斷一個原子類型是否屬于無鎖數(shù)據(jù)結(jié)構(gòu): 所有標(biāo)準(zhǔn)原子類型( std::atomic_flag 除外,因為

    2024年02月10日
    瀏覽(28)
  • java JUC并發(fā)編程 第六章 CAS

    java JUC并發(fā)編程 第六章 CAS

    第一章 java JUC并發(fā)編程 Future: link 第二章 java JUC并發(fā)編程 多線程鎖: link 第三章 java JUC并發(fā)編程 中斷機(jī)制: link 第四章 java JUC并發(fā)編程 java內(nèi)存模型JMM: link 第五章 java JUC并發(fā)編程 volatile與JMM: link 第六章 java JUC并發(fā)編程 CAS: link 第七章 java JUC并發(fā)編程 原子操作類增強(qiáng): link 第八章

    2024年02月10日
    瀏覽(23)
  • java JUC并發(fā)編程 第九章 對象內(nèi)存布局與對象頭

    java JUC并發(fā)編程 第九章 對象內(nèi)存布局與對象頭

    第一章 java JUC并發(fā)編程 Future: link 第二章 java JUC并發(fā)編程 多線程鎖: link 第三章 java JUC并發(fā)編程 中斷機(jī)制: link 第四章 java JUC并發(fā)編程 java內(nèi)存模型JMM: link 第五章 java JUC并發(fā)編程 volatile與JMM: link 第六章 java JUC并發(fā)編程 CAS: link 第七章 java JUC并發(fā)編程 原子操作類增強(qiáng): link 第八章

    2024年02月07日
    瀏覽(18)
  • 【并發(fā)編程】JUC并發(fā)編程(徹底搞懂JUC)

    【并發(fā)編程】JUC并發(fā)編程(徹底搞懂JUC)

    如果你對多線程沒什么了解,那么從入門模塊開始。 如果你已經(jīng)入門了多線程(知道基礎(chǔ)的線程創(chuàng)建、死鎖、synchronized、lock等),那么從juc模塊開始。 新手學(xué)技術(shù)、老手學(xué)體系,高手學(xué)格局。 JUC實際上就是我們對于jdk中java.util .concurrent 工具包的簡稱 ,其結(jié)構(gòu)如下: 這個包

    2024年02月20日
    瀏覽(20)
  • JUC并發(fā)編程(二)

    JUC并發(fā)編程(二)

    JUC并發(fā)編程(續(xù)) 接上一篇筆記:https://blog.csdn.net/weixin_44780078/article/details/130694996 五、Java內(nèi)存模型 JMM 即 Java Memory Model,它定義了主存、工作內(nèi)存抽象概念,底層對應(yīng)著CPU寄存器、緩存、硬件內(nèi)存、CPU 指令優(yōu)化等。 JMM 體現(xiàn)在以下幾個方面: 原子性:保證指令不會受到線程

    2024年02月05日
    瀏覽(27)
  • 第九章 JUC并發(fā)編程

    第九章 JUC并發(fā)編程

    http://t.csdn.cn/UgzQi 使用 AQS加 Lock 接口實現(xiàn)簡單的不可重入鎖 早期程序員會自己通過一種同步器去實現(xiàn)另一種相近的同步器,例如用可重入鎖去實現(xiàn)信號量,或反之。這顯然不夠優(yōu)雅,于是在 JSR166(java 規(guī)范提案)中創(chuàng)建了 AQS,提供了這種通用的同步器機(jī)制。 AQS 要實現(xiàn)的功能

    2023年04月08日
    瀏覽(21)
  • 【JUC并發(fā)編程】

    【JUC并發(fā)編程】

    本筆記內(nèi)容為狂神說JUC并發(fā)編程部分 目錄 一、什么是JUC 二、線程和進(jìn)程 1、概述? 2、并發(fā)、并行 3、線程有幾個狀態(tài)? 4、wait/sleep 區(qū)別 三、Lock鎖(重點(diǎn))? 四、生產(chǎn)者和消費(fèi)者問題 五、八鎖現(xiàn)象 六、集合類不安全? 七、Callable ( 簡單 ) 八、常用的輔助類(必會) 1、CountDown

    2024年02月09日
    瀏覽(11)
  • JUC并發(fā)編程14 | ThreadLocal

    JUC并發(fā)編程14 | ThreadLocal

    尚硅谷JUC并發(fā)編程(100-111) ThreadLocal是什么? ThreadLocal 提供 線程局部變量 。這些變量與正常的變量有所不同,因為每一個線程在訪問ThreadLocal實例的時候(通過其get或set方法)都有自己的、獨(dú)立初始化的變量副本。ThreadLocal實例通常是類中的私有靜態(tài)字段,使用它的目的是

    2024年02月04日
    瀏覽(23)
  • JUC 高并發(fā)編程基礎(chǔ)篇

    JUC 高并發(fā)編程基礎(chǔ)篇

    ? 1、什么是 JUC ? 2、Lock 接口 ? 3、線程間通信 ? 4、集合的線程安全 ? 5、多線程鎖 ? 6、Callable 接口 ? 7、JUC 三大輔助類: CountDownLatch CyclicBarrier Semaphore ? 8、讀寫鎖: ReentrantReadWriteLock ? 9、阻塞隊列 ? 10、ThreadPool 線程池 ? 11、Fork/Join 框架 ? 12、CompletableFuture 1 什么

    2024年02月07日
    瀏覽(21)
  • 【JUC并發(fā)編程】讀寫鎖:ReadWriteLock

    【JUC并發(fā)編程】讀寫鎖:ReadWriteLock

    1. 不使用讀寫鎖 2. 使用讀寫鎖 ReadWriteLock讀寫鎖特點(diǎn) ① 寫鎖是獨(dú)占鎖,一次只能被一個線程占有 ② 讀鎖是共享鎖,多個線程可以同時占有 讀-讀:可以共存 讀-寫:不能共存 寫-寫:不能共存

    2024年02月13日
    瀏覽(23)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包