0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Java atomic中set()和lazySet()的區(qū)別

科技綠洲 ? 來源:Java技術(shù)指北 ? 作者:Java技術(shù)指北 ? 2023-10-09 14:21 ? 次閱讀

在本教程中,我們將講講 Java atomic 類(如 AtomicIntegerAtomicReference )的方法 set()lazySet() 之間的區(qū)別。

原子變量

Java中的原子變量使我們能夠輕松地對類的引用或字段進(jìn)行線程安全的操作,而不需要添加監(jiān)視器或互斥等并發(fā)原語。

它們被定義在 java.util.concurrent.atomic 包下,雖然它們的API根據(jù)原子類型的不同而不同,但大多數(shù)都支持set()lazySet()方法。

為了簡單起見,我們將在本文中使用 AtomicReferenceAtomicInteger,但同樣的原則適用于其他原子類型。

3.The set() 方法

在調(diào)用set()后,當(dāng)我們從不同的線程使用get()方法訪問該字段時(shí),該變化是立即可見的。這意味著該值被從CPU緩存中刷新到了所有CPU核共有的內(nèi)存層。為了展示上述功能,讓我們創(chuàng)建一個(gè)最小的 producer-consumer 控制臺(tái)應(yīng)用。

public class Application {
    
        AtomicInteger atomic = new AtomicInteger(0);
    
        public static void main(String[] args) {
            Application app = new Application();
            new Thread(() - > {
                for (int i = 0; i < 10; i++) {
                    app.atomic.set(i);
                    System.out.println("Set: " + i);
                    Thread.sleep(100);
                }
            }).start();
    
            new Thread(() - > {
                for (int i = 0; i < 10; i++) {
                    synchronized (app.atomic) {
                        int counter = app.atomic.get();
                        System.out.println("Get: " + counter);
                    }
                    Thread.sleep(100);
                }
            }).start();
        }
    }

在控制臺(tái),我們應(yīng)該看到一系列的 "設(shè)置 "和 "獲取 "信息。

Set: 3
    Set: 4
    Get: 4
    Get: 5

表明緩存一致性的是,"Get "語句中的值總是等于或大于其上方的 "Set "語句中的值。。

這種行為雖然非常有用,但也帶來了性能上的影響。如果我們能在不需要緩存一致性的情況下避免它,那就太好了。

The lazySet() 方法

lazySet()方法與set()方法相同,但沒有緩存刷新。

換句話說,我們的變化最終只對其他線程可見。這意味著從不同的線程對更新的 AtomicReference 調(diào)用 get()可能會(huì)給我們帶來舊的值。

為了看到這一點(diǎn),讓我們在之前的控制臺(tái)應(yīng)用程序中改變第一個(gè)線程的Runnable。

for (int i = 0; i < 10; i++) {
    app.atomic.lazySet(i);
    System.out.println("Set: " + i);
    Thread.sleep(100);
}

新的 "設(shè)置 "和 "獲取 "信息可能不總是遞增的。

Set: 4
Set: 5
Get: 4
Get: 5

由于線程的特性,我們可能需要重新運(yùn)行幾次應(yīng)用程序,以便觸發(fā)這種行為。盡管生產(chǎn)者線程已經(jīng)將AtomicInteger設(shè)置為5,但消費(fèi)者線程還是先檢索到了值4,這意味著當(dāng)lazySet()被使用時(shí),系統(tǒng)最終是一致的。

在更多的技術(shù)術(shù)語中,我們說lazySet()方法在代碼中不作為發(fā)生在前的邊,與它們的set()對應(yīng)的方法相反。

什么時(shí)候使用lazySet()?

我們并不清楚什么時(shí)候應(yīng)該使用lazySet(),因?yàn)樗cset()的區(qū)別很微妙。我們需要仔細(xì)分析這個(gè)問題,不僅要確保我們會(huì)得到性能上的提升,還要確保在多線程環(huán)境下的正確性。

我們可以使用的一種方式是,一旦我們不再需要一個(gè)對象的引用,就用null替換它。這樣,我們表明該對象有資格進(jìn)行垃圾回收,而不會(huì)產(chǎn)生任何性能上的損失。我們假設(shè)其他線程可以使用廢棄的值,直到他們看到AtomicReferencenull。不過一般來說,我們應(yīng)該使用lazySet(),當(dāng)我們想對一個(gè)原子變量進(jìn)行修改,而且我們知道這個(gè)修改不需要立即對其他線程可見。

總結(jié)

在這篇文章中,我們看了原子類的set()lazySet()方法之間的區(qū)別。我們還學(xué)習(xí)了何時(shí)使用哪種方法。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報(bào)投訴
  • 內(nèi)存
    +關(guān)注

    關(guān)注

    8

    文章

    2966

    瀏覽量

    73815
  • JAVA
    +關(guān)注

    關(guān)注

    19

    文章

    2952

    瀏覽量

    104484
  • API
    API
    +關(guān)注

    關(guān)注

    2

    文章

    1472

    瀏覽量

    61749
  • SET
    SET
    +關(guān)注

    關(guān)注

    0

    文章

    17

    瀏覽量

    7928
  • 線程安全
    +關(guān)注

    關(guān)注

    0

    文章

    13

    瀏覽量

    2454
收藏 人收藏

    評論

    相關(guān)推薦

    JAVA和C++區(qū)別

    和c++的相似之處多于不同之處,但兩種語言問幾處主要的不同使得Java更容易學(xué)習(xí),并且編程環(huán)境更為簡單。 我在這里不能完全列出不同之處,僅列出比較顯著的區(qū)別: 1.指針 JAVA語言讓編程者無法找到
    發(fā)表于 04-11 15:19

    JAVA和C++區(qū)別

    和c++的相似之處多于不同之處,但兩種語言問幾處主要的不同使得Java更容易學(xué)習(xí),并且編程環(huán)境更為簡單。 我在這里不能完全列出不同之處,僅列出比較顯著的區(qū)別: 1.指針 JAVA語言讓編程者無法找到指針
    發(fā)表于 10-10 14:50

    Java和C++的區(qū)別

    和c++的相似之處多于不同之處,但兩種語言問幾處主要的不同使得Java更容易學(xué)習(xí),并且編程環(huán)境更為簡單。 我在這里不能完全列出不同之處,僅列出比較顯著的區(qū)別: 1.指針 JAVA語言讓編程者無法找到指針
    發(fā)表于 09-13 16:02

    this的使用場景及與C,Java的this的區(qū)別

    【JS】this有哪些使用場景?跟C,Java的this有什么區(qū)別?如何改變this的值?
    發(fā)表于 03-11 10:17

    Java SE、Java EE、Java ME之間的區(qū)別

    本文把JAVA SE、JAVA EE、JAVA ME拿來做下區(qū)別,同時(shí)也分享一下作者的一些成果。目前的Java平臺(tái)根據(jù)軟件開發(fā)人員、服務(wù)提供
    發(fā)表于 07-11 08:31

    JAVA SE、JAVA EE和JAVA ME有什么區(qū)別

    本文把JAVA SE、JAVA EE、JAVAME拿來做下區(qū)別,同時(shí)也分享一下作者的一些成果。目前的Java平臺(tái)根據(jù)軟件開發(fā)人員、服務(wù)提供商和設(shè)備生產(chǎn)商可以針對特定的市場可以分為三個(gè)版
    發(fā)表于 07-15 07:11

    Java基礎(chǔ)概念

    1.什么是原子操作?在Java Concurrency API中有哪些原子類(atomic classes)?原子操作(atomic operation)意為"不可被中斷的一個(gè)或一系列操作" 。
    發(fā)表于 08-02 06:00

    一文看懂scala和java區(qū)別

    本文開始對Scala的概念進(jìn)行了詳細(xì)說明,其次闡述了Java的定義以及Java的工作原理,最后闡述了scala和java區(qū)別以及scala相對于j
    的頭像 發(fā)表于 03-07 18:30 ?6.5w次閱讀
    一文看懂scala和<b class='flag-5'>java</b>的<b class='flag-5'>區(qū)別</b>

    java學(xué)習(xí)—null和isEmpty 區(qū)別

    本文檔內(nèi)容介紹了基于java學(xué)習(xí)null和isEmpty 區(qū)別,供參考
    發(fā)表于 03-13 10:26 ?0次下載

    python之集合set的基本步驟分享

    區(qū)別就是remove的元素在set當(dāng)中沒有的話會(huì)報(bào)錯(cuò),而discard不會(huì)
    的頭像 發(fā)表于 08-23 10:31 ?2138次閱讀

    如何區(qū)分Javaprint和println

    在最開始學(xué)習(xí)Java的時(shí)候?qū)W到sout+enter鍵可以輸出結(jié)果,顯示的是System.out.println();而在Python是直接使用print。那么在Javaprint和
    的頭像 發(fā)表于 02-21 15:10 ?1202次閱讀

    javaweb和java有什么區(qū)別

    Javaweb和Java是兩個(gè)不同的概念,它們之間存在明顯的區(qū)別。下面將詳細(xì)介紹這兩者的區(qū)別,以滿足你關(guān)于詳盡、詳實(shí)、細(xì)致的要求。 Java是一種廣泛應(yīng)用的編程語言和計(jì)算平臺(tái),它具有跨
    的頭像 發(fā)表于 11-16 10:49 ?3366次閱讀

    java的重載和重寫的區(qū)別

    Java的重載(Overload)和重寫(Override)是兩個(gè)重要的面向?qū)ο缶幊谈拍?,盡管它們在使用和功能上有所不同,但它們都與方法和多態(tài)性相關(guān)。本文將全面介紹重載和重寫的概念、語法
    的頭像 發(fā)表于 11-17 17:13 ?619次閱讀

    pythonset類型

    Pythonset類型是一種無序、可變的集合數(shù)據(jù)類型,它的主要特點(diǎn)是不允許重復(fù)元素的存在。本文將詳盡、詳實(shí)、細(xì)致地介紹set類型的使用場景、常用操作以及與其他類型的比較等方面,以幫助讀者全面了解
    的頭像 發(fā)表于 11-21 16:25 ?783次閱讀

    華納云:java web和java有什么區(qū)別java web和java有什么區(qū)別

    Java Web和Java是兩個(gè)不同的概念,它們在功能、用途和實(shí)現(xiàn)方式上存在一些區(qū)別,下面將詳細(xì)介紹它們之間的區(qū)別。 1. 功能和用途: – Jav
    的頭像 發(fā)表于 07-16 13:35 ?617次閱讀
    華納云:<b class='flag-5'>java</b> web和<b class='flag-5'>java</b>有什么<b class='flag-5'>區(qū)別</b><b class='flag-5'>java</b> web和<b class='flag-5'>java</b>有什么<b class='flag-5'>區(qū)別</b>