国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Java多線程環境下對象安全的構建方式

xuexiangjys / 3329人閱讀

摘要:在構建一個對象的過程中,更要考慮到多線程間共享數據的一致性問題,否則很可能會發生一個在線程中構建完整的對象,在線程中看到的卻只被構建了一部分。例如下面的代碼上面的代碼本意是想實現一個單例模式,但在多線程環境下,這個單例模式將很容易被打破。

在上一篇文章《從Java多線程可見性談Happens-Before原則》中,我們詳細討論了在并發編程中Happens-Before原則對多線程共享變量的重要性。要想確保讓一個線程對共享變量的修改能被其它線程感知到,就必須讓兩個線程中的操作滿足Happens-Before原則。
在構建一個對象的過程中,更要考慮到多線程間共享數據的一致性問題,否則很可能會發生一個在A線程中構建完整的對象,在B線程中看到的卻只被構建了一部分。例如下面的代碼:

public class UnsafeLazyInitialization {
    private static Resource resource;
    
    public static Resource getInstance() {
        if(resource == null) {
            resource = new Resource();
        }
        return resource;
    }
}

上面的代碼本意是想實現一個單例模式,但在多線程環境下,這個單例模式將很容易被打破。
首先,resource是一個普通變量,當一個線程更新resource變量的值時,其它線程可能無法感知到resource引用已經指向了一個創建好的對象,所以可能會導致程序創建多個Resource對象。
更糟糕的是重排序,在線程A中是先初始化Resource對象的各個field之后再將resource引用設置為指向它,線程B看到的可能是對引用變量resource的寫入操作在對Resource對象各個field的寫入操作之前發生。這會導致線程B看到的是一個被部分構造的Resource對象實例,該對象可能處于無效狀態。
為了解決上面的問題,我們可以套用Happens-Before規則。例如在getInstance方法上聲明synchronized。
然而對于構建一個對象實例的操作,除了可以使用Happens-Before原則外,我們利用下面兩種方式也可以保證對象的構建狀態被正確發布到其它線程。

靜態初始化器

靜態初始化器是由JVM在的初始化階段執行,即在類被加載后并且被線程使用前。在靜態初始化期間,內存寫入操作將自動對所有線程可見。所以上面的程序改下成如下代碼將會確保Resource對象被正確發布到其它線程:

public class EagerInitialization {
    private static Resource resource = new Resource();
    
    public static Resource getInstance() {
        return resource;
    }
}
含有final域的對象

對于含有final域的對象,初始化安全性可以防止對對象引用的寫入操作被重排序到對象構造過程之前。在構造函數完成時,構造函數對final域的所有寫入操作,以及通過final域可以到達的任何變量的寫入操作,都能夠被獲取到該對象引用的線程看到。例如下面的代碼:

public class FinalInitialization {
    private static final Resource resource;
    
    public static Resource getInstance() {
        if(resource == null) {
            resource = new Resource();
        }
        return resource;
    }
}

在上面的代碼中,將resource變量聲明為final類型的。這樣可以保證,無論哪個線程,只要獲取到對象的引用的值,就一定可以看到一個被完整構建的Resource對象。
但是此處的resource引用變量本身仍然需要其他機制保證可以對其它線程可見。

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/67704.html

相關文章

  • 學習Java線程一些總結

    摘要:多線程環境下的一些問題安全性問題在沒有正確同步的情況下,多線程環境下程序可能得出錯誤的結果。一些相關概念競爭條件多線程的環境下,程序執行的結果取決于線程交替執行的方式。而線程的交替操作順序是不可預測的,如此程序執行的結果也是不可預測的。 入口 Java多線程的應用復雜性之如jvm有限的幾個內存方面的操作和規范,就像無數紛繁復雜的應用邏輯建立在有限的指令集上。 如何寫出線程安全的程序,有...

    coolpail 評論0 收藏0
  • 線程安全

    摘要:不可變在中,不可變的對象一定是線程安全的。在里標注自己是線程安全的類,大多都不是絕對線程安全,比如某些情況下類在調用端也需要額外的同步措施。無同步方案要保證線程安全,不一定就得需要數據的同步,兩者沒有因果關系。 在之前學習編程的時候,有一個概念根深蒂固,即程序=算法+數據結構。數據代表問題空間中的客體,代碼就用來處理這些數據,這種思維是站在計算機的角度去抽象問題和解決問題,稱之為面向過...

    fuyi501 評論0 收藏0
  • Java集合總結

    摘要:概述集合類主要有大分支,及。不能保證元素的排列順序,順序有可能發生變化不是同步的集合元素可以是但只能放入一個是接口的唯一實現類,可以確保集合元素處于排序狀態。如果這兩個的通過比較返回,新添加的將覆蓋集合中原有的,但不會覆蓋。 概述 Java集合類主要有2大分支,Collection及Map。Collection體系如下: https://upload-images.jianshu......

    toddmark 評論0 收藏0
  • 想進大廠?50個線程面試題,你會少?(一)

    摘要:下面是線程相關的熱門面試題,你可以用它來好好準備面試。線程安全問題都是由全局變量及靜態變量引起的。持有自旋鎖的線程在之前應該釋放自旋鎖以便其它線程可以獲得自旋鎖。 最近看到網上流傳著,各種面試經驗及面試題,往往都是一大堆技術題目貼上去,而沒有答案。 不管你是新程序員還是老手,你一定在面試中遇到過有關線程的問題。Java語言一個重要的特點就是內置了對并發的支持,讓Java大受企業和程序員...

    wow_worktile 評論0 收藏0
  • java入門

    摘要:包含了支持服務開發的類,并為提供基礎,如語言基礎操作操作網絡通信以及多線程等技術。在運行文件時,的解釋器對這些字節碼進行解釋執行,執行過程中需要加入的類在連接階段被載入到運行環境中。支持多個線程同時執行,并提供多線程之間的同步機制。 1.什么是Java語言 簡單地說,Java 是由 Sun Microsystems 公司于 1995 年推出的一門面向對象程序設計語言。2009 年 Or...

    zhangfaliang 評論0 收藏0

發表評論

0條評論

xuexiangjys

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<