成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

Java多線程環(huán)境下對(duì)象安全的構(gòu)建方式

xuexiangjys / 3399人閱讀

摘要:在構(gòu)建一個(gè)對(duì)象的過程中,更要考慮到多線程間共享數(shù)據(jù)的一致性問題,否則很可能會(huì)發(fā)生一個(gè)在線程中構(gòu)建完整的對(duì)象,在線程中看到的卻只被構(gòu)建了一部分。例如下面的代碼上面的代碼本意是想實(shí)現(xiàn)一個(gè)單例模式,但在多線程環(huán)境下,這個(gè)單例模式將很容易被打破。

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

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

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

靜態(tài)初始化器

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

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

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

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

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

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/67704.html

相關(guān)文章

  • 學(xué)習(xí)Java線程一些總結(jié)

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

    coolpail 評(píng)論0 收藏0
  • 線程安全

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

    fuyi501 評(píng)論0 收藏0
  • Java集合總結(jié)

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

    toddmark 評(píng)論0 收藏0
  • 想進(jìn)大廠?50個(gè)線程面試題,你會(huì)少?(一)

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

    wow_worktile 評(píng)論0 收藏0
  • java入門

    摘要:包含了支持服務(wù)開發(fā)的類,并為提供基礎(chǔ),如語言基礎(chǔ)操作操作網(wǎng)絡(luò)通信以及多線程等技術(shù)。在運(yùn)行文件時(shí),的解釋器對(duì)這些字節(jié)碼進(jìn)行解釋執(zhí)行,執(zhí)行過程中需要加入的類在連接階段被載入到運(yùn)行環(huán)境中。支持多個(gè)線程同時(shí)執(zhí)行,并提供多線程之間的同步機(jī)制。 1.什么是Java語言 簡單地說,Java 是由 Sun Microsystems 公司于 1995 年推出的一門面向?qū)ο蟪绦蛟O(shè)計(jì)語言。2009 年 Or...

    zhangfaliang 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

xuexiangjys

|高級(jí)講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<