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

資訊專欄INFORMATION COLUMN

Java 并發(fā)學(xué)習(xí)筆記(一)——原子性、可見性、有序性問題

Chao / 2618人閱讀

摘要:最后,總結(jié)一下,導(dǎo)致并發(fā)問題的三個源頭分別是原子性一個線程在執(zhí)行的過程當中不被中斷??梢娦砸粋€線程修改了共享變量,另一個線程能夠馬上看到,就叫做可見性。

計算機的 CPU、內(nèi)存、I/O 設(shè)備的速度一直存在較大的差異,依次是 CPU > 內(nèi)存 > I/O 設(shè)備,為了權(quán)衡這三者的速度差異,主要提出了三種解決辦法:

CPU 增加了緩存,均衡和內(nèi)存的速度差異

發(fā)明了進程、線程,分時復(fù)用 CPU,提高 CPU 的使用效率

編譯指令優(yōu)化,更好的利用緩存

三種解決辦法雖然有效,但是也帶來了另外的三個問題,分別就是并發(fā) bug 產(chǎn)生的源頭。

1.可見性問題

如果是單核 CPU,多個線程操作的都是同一個 CPU 緩存,那么一個線程修改了共享變量,另一個線程肯定能馬上看到。

如果是多核 CPU ,每個 CPU 都有自己的緩存,這樣線程對共享變量的修改便對其他線程不可見了。

2.原子性問題

為什么會有線程切換?一個線程在執(zhí)行的過程中,可能會進行耗時的 I/O 操作,這時線程需要等待 I/O 操作完成。線程在等待的過程中,可以釋放 CPU 的使用權(quán),讓另一個線程執(zhí)行,這樣能夠提高 CPU 的使用率。

例如上圖,兩個線程同時對變量 count 加 1,線程 A 在執(zhí)行的過程中切換到了線程 B,最后導(dǎo)致寫入到內(nèi)存的值都是 1,與預(yù)期不符。

3.有序性問題

首先看一段很經(jīng)典的獲取單例對象的代碼:

public class Singleton {
    
    private static Singleton instance;
     //Java 獲取單例對象
    public Singleton getInstance(){
        if (instance == null){
            synchronized (Singleton.class){
                if (instance == null){
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

程序的邏輯是:首先判斷 instance 是否為空,如果為空,對其加鎖,然后再判斷是否為空,此時為空的話則初始化 instance 對象。

如果線程 A 和 B 同時執(zhí)行方法,在 synchronized 處,一個線程會被阻塞,假設(shè)被阻塞的是線程 B,此時線程 A 進入并初始化 instance,然后喚醒線程 B,線程 B 進入的時候,發(fā)現(xiàn) instance 不為空了,所以不會創(chuàng)建對象。

但是因為有序性問題的存在,這段代碼也不是想象的那么完美,我們期望的初始化對象的過程是這樣的:1.分配內(nèi)存;2.初始化對象;3.將內(nèi)存地址賦給 instance。但是經(jīng)過編譯優(yōu)化之后,卻是這樣的:

1.分配內(nèi)存

2.將內(nèi)存地址賦給 instance

3.在內(nèi)存上面初始化對象

這樣,如果線程 A 執(zhí)行到了第二步,然后切換到 線程 B,線程 B 就會認為 instance 不為空然后直接返回了,實際上 instance 并沒有初始化。

最后,總結(jié)一下,導(dǎo)致并發(fā)問題的三個源頭分別是

原子性:一個線程在執(zhí)行的過程當中不被中斷。

可見性:一個線程修改了共享變量,另一個線程能夠馬上看到,就叫做可見性。

有序性:編譯指令重排導(dǎo)致的問題。

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

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/74507.html

相關(guān)文章

  • 多線程學(xué)習(xí)筆記(1):volatile和synchronized

    摘要:今天開始整理學(xué)習(xí)多線程的知識,談?wù)勛钪匾膬蓚€關(guān)鍵字和。但是這樣一個過程比較慢,在使用多線程的時候就會出現(xiàn)問題。有序性有序性是指多線程執(zhí)行結(jié)果的正確性。這種機制在多線程中會出現(xiàn)問題,因此可以通過來禁止重排。 今天開始整理學(xué)習(xí)多線程的知識,談?wù)勛钪匾膬蓚€關(guān)鍵字:volatile和synchronized。 一、三個特性 1、原子性 所謂原子性操作就是指這些操作是不可中斷的,要么執(zhí)行過程...

    jk_v1 評論0 收藏0
  • 來,了解Java內(nèi)存模型(JMM)

    摘要:因為管理人員是了解手下的人員以及自己負責(zé)的事情的。處理器優(yōu)化和指令重排上面提到在在和主存之間增加緩存,在多線程場景下會存在緩存一致性問題。有沒有發(fā)現(xiàn),緩存一致性問題其實就是可見性問題。 網(wǎng)上有很多關(guān)于Java內(nèi)存模型的文章,在《深入理解Java虛擬機》和《Java并發(fā)編程的藝術(shù)》等書中也都有關(guān)于這個知識點的介紹。但是,很多人讀完之后還是搞不清楚,甚至有的人說自己更懵了。本文,就來整體的...

    kviccn 評論0 收藏0
  • 來,了解Java內(nèi)存模型(JMM)

    摘要:因為管理人員是了解手下的人員以及自己負責(zé)的事情的。處理器優(yōu)化和指令重排上面提到在在和主存之間增加緩存,在多線程場景下會存在緩存一致性問題。有沒有發(fā)現(xiàn),緩存一致性問題其實就是可見性問題。 網(wǎng)上有很多關(guān)于Java內(nèi)存模型的文章,在《深入理解Java虛擬機》和《Java并發(fā)編程的藝術(shù)》等書中也都有關(guān)于這個知識點的介紹。但是,很多人讀完之后還是搞不清楚,甚至有的人說自己更懵了。本文,就來整體的...

    eccozhou 評論0 收藏0
  • Java并發(fā)】線程安全

    摘要:另一個是使用鎖的機制來處理線程之間的原子性。依賴于去實現(xiàn)鎖,因此在這個關(guān)鍵字作用對象的作用范圍內(nèi),都是同一時刻只能有一個線程對其進行操作的。 線程安全性 定義:當多個線程訪問某個類時,不管運行時環(huán)境采用何種調(diào)度方式或者這些線程將如何交替執(zhí)行,并且在主調(diào)代碼中不需要任何額外的同步或協(xié)同,這個類都能表現(xiàn)出正確的行為,那么就稱這個類是線程安全的。 線程安全性主要體現(xiàn)在三個方面:原子性、可見性...

    劉玉平 評論0 收藏0

發(fā)表評論

0條評論

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