成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

【Java并發(fā)】線程安全性

劉玉平 / 2263人閱讀

摘要:另一個(gè)是使用鎖的機(jī)制來處理線程之間的原子性。依賴于去實(shí)現(xiàn)鎖,因此在這個(gè)關(guān)鍵字作用對(duì)象的作用范圍內(nèi),都是同一時(shí)刻只能有一個(gè)線程對(duì)其進(jìn)行操作的。

線程安全性

定義:當(dāng)多個(gè)線程訪問某個(gè)類時(shí),不管運(yùn)行時(shí)環(huán)境采用何種調(diào)度方式或者這些線程將如何交替執(zhí)行,并且在主調(diào)代碼中不需要任何額外的同步或協(xié)同,這個(gè)類都能表現(xiàn)出正確的行為,那么就稱這個(gè)類是線程安全的。

線程安全性主要體現(xiàn)在三個(gè)方面:原子性、可見性、有序性:

原子性:提供了互斥訪問,同一時(shí)刻只能有一個(gè)線程來對(duì)它進(jìn)行操作

可見性:一個(gè)線程對(duì)主內(nèi)存的修改可以及時(shí)地被其他線程觀察到

有序性:一個(gè)線程觀察其他線程中的指令執(zhí)行順序,由于指令重排序的存在,該觀察結(jié)果一般雜亂無序

原子性

原子性在 JDK 中主要由兩個(gè)方面體現(xiàn)出來:

Atomic

一個(gè)是 JDK 中已經(jīng)提供好的 Atomic 包,它們均使用了 CAS 完成線程的原子性操作(詳見【Java并發(fā)】淺析 AtomicLong & LongAdder)。

另一個(gè)是使用鎖的機(jī)制來處理線程之間的原子性。鎖主要包括:synchronized、lock。

synchronized

依賴于 JVM 去實(shí)現(xiàn)鎖,因此在這個(gè)關(guān)鍵字作用對(duì)象的作用范圍內(nèi),都是同一時(shí)刻只能有一個(gè)線程對(duì)其進(jìn)行操作的。synchronized 是 Java 中的一個(gè)關(guān)鍵字,是一種同步鎖。它可以修飾的對(duì)象主要有四種:

修飾代碼塊:大括號(hào)括起來的代碼,作用于調(diào)用的對(duì)象

修飾方法:整個(gè)方法,作用于調(diào)用的對(duì)象

修飾靜態(tài)方法:整個(gè)靜態(tài)方法,作用于所有對(duì)象

修飾類:括號(hào)括起來的部分,作用于所有對(duì)象

注意:如果當(dāng)前類是一個(gè)父類,子類調(diào)用父類的被 synchronized 修飾的方法,不會(huì)攜帶 synchronized 屬性,因?yàn)?synchronized 不屬于方法聲明的一部分。
Lock

首先要說明的就是 Lock,通過查看 Lock 的源碼可知,Lock 是一個(gè)接口。ReentrantLock 是唯一實(shí)現(xiàn)了 Lock 接口的類,意思是“可重入鎖”,并且 ReentrantLock 提供了更多的方法。

public interface Lock {
    void lock();
    void lockInterruptibly() throws InterruptedException;
    boolean tryLock();
    boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
    void unlock();
    Condition newCondition();
}

鎖的分類

可重入鎖

synchronized / ReentrantLock

可中斷鎖

synchronized 不可中斷,Lock 可中斷

公平鎖

synchronized 非公平鎖

ReentrantLockReentrantReadWriteLock 默認(rèn)情況下非公平鎖,可設(shè)置為公平鎖

讀寫鎖

ReadWriteLock / ReentrantReadWriteLock

可見性

導(dǎo)致共享變量在線程間不可見的原因:

線程交叉執(zhí)行

重排序結(jié)合線程交叉執(zhí)行

共享變量更新后的值沒有在工作內(nèi)存與主存間及時(shí)更新

JVM 對(duì)于可見性,提供了 synchronized 和 volatile:

synchronized

JMM 關(guān)于 synchronized 的兩條規(guī)定:

線程解鎖前,必須把共享變量的最新值刷新到主內(nèi)存

線程加鎖時(shí),將清空工作內(nèi)存中共享變量的值,從而使用共享變量時(shí)需要從主內(nèi)存中重新讀取最新的值(注意:加鎖與解鎖是同一把鎖

volatile

volatile 的方式是:通過加入內(nèi)存屏障禁止重排序優(yōu)化來實(shí)現(xiàn)。

對(duì) volatile 變量寫操作時(shí),會(huì)在寫操作后加入一條 store 屏障指令,將本地內(nèi)存中的共享變量值刷新到主內(nèi)存。

對(duì) volatile 變量讀操作時(shí),會(huì)在讀操作前加入一條 load 屏障指令,從主內(nèi)存中讀取共享變量。

volatile的屏障操作都是 cpu 級(jí)別的;適合狀態(tài)驗(yàn)證,不適合累加值,volatile關(guān)鍵字不具有原子性。

適合狀態(tài)驗(yàn)證,不適合累加值,volatile關(guān)鍵字不具有原子性

有序性

Java 內(nèi)存模型中,允許編譯器和處理器對(duì)指令進(jìn)行重排序,但是重排序過程不會(huì)影響到單線程程序的執(zhí)行,卻會(huì)影響到多線程并發(fā)執(zhí)行的正確性。而 Java 提供了 volatile、synchronized、Lock,它們可以用來保證有序性。

另外,Java 內(nèi)存模型具備一些先天的有序性,即不需要任何手段就能得到保證的有序性。通常被我們稱為happens-before 原則(先行發(fā)生原則)。如果兩個(gè)線程的執(zhí)行順序無法從 happens-before 原則推導(dǎo)出來,那么就不能保證它們的有序性,虛擬機(jī)就可以對(duì)它們進(jìn)行重排序。

【以下規(guī)則摘抄自《深入理解Java虛擬機(jī)》】

程序次序規(guī)則:一個(gè)線程內(nèi),按照代碼順序,書寫在前面的操作先行發(fā)生于書寫在后面的操作

鎖定規(guī)則:一個(gè)unlock操作先行發(fā)生于后面對(duì)同一個(gè)鎖的lock操作

volatile變量規(guī)則:對(duì)一個(gè)變量的寫操作先行發(fā)生于后面對(duì)這個(gè)變量的讀操作(重要)

傳遞規(guī)則:如果操作A先行發(fā)生于操作B,而操作B又先行發(fā)生于操作C,則可以得出操作A先行發(fā)生于操作C

線程啟動(dòng)規(guī)則:Thread對(duì)象的start()方法先行發(fā)生于此線程的每一個(gè)動(dòng)作

線程中斷規(guī)則:對(duì)線程interrupt()方法的調(diào)用先行發(fā)生于被中斷線程的代碼檢測(cè)到中斷事件的發(fā)生

線程終結(jié)規(guī)則:線程中所有的操作都先行發(fā)生于線程的終止檢測(cè),我們可以通過Thread.join()方法結(jié)束、Thread.isAlive()的返回值手段檢測(cè)到線程已經(jīng)終止執(zhí)行

思維導(dǎo)圖

筆記整理自:【IMOOC】Java并發(fā)編程與高并發(fā)解決方案

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/73294.html

相關(guān)文章

  • 第10章:并發(fā)和分布式編程 10.1并發(fā)性和線程全性

    摘要:并發(fā)模塊本身有兩種不同的類型進(jìn)程和線程,兩個(gè)基本的執(zhí)行單元。調(diào)用以啟動(dòng)新線程。在大多數(shù)系統(tǒng)中,時(shí)間片發(fā)生不可預(yù)知的和非確定性的,這意味著線程可能隨時(shí)暫?;蚧謴?fù)。 大綱 什么是并發(fā)編程?進(jìn)程,線程和時(shí)間片交織和競爭條件線程安全 策略1:監(jiān)禁 策略2:不可變性 策略3:使用線程安全數(shù)據(jù)類型 策略4:鎖定和同步 如何做安全論證總結(jié) 什么是并發(fā)編程? 并發(fā)并發(fā)性:多個(gè)計(jì)算同時(shí)發(fā)生。 在現(xiàn)代...

    instein 評(píng)論0 收藏0
  • [Java并發(fā)-11] 并發(fā)容器的使用

    摘要:同步容器及其注意事項(xiàng)中的容器主要可以分為四個(gè)大類,分別是和,但并不是所有的容器都是線程安全的。并發(fā)容器及其注意事項(xiàng)在版本之前所謂的線程安全的容器,主要指的就是同步容器,當(dāng)然因?yàn)樗蟹椒ǘ加脕肀WC互斥,串行度太高了,性能太差了。 Java 并發(fā)包有很大一部分內(nèi)容都是關(guān)于并發(fā)容器的,因此學(xué)習(xí)和搞懂這部分的內(nèi)容很有必要。 Java 1.5 之前提供的同步容器雖然也能保證線程安全,但是性能很差...

    legendaryedu 評(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并發(fā)編程筆記(二)

    摘要:本文探討并發(fā)中的其它問題線程安全可見性活躍性等等。當(dāng)閉鎖到達(dá)結(jié)束狀態(tài)時(shí),門打開并允許所有線程通過。在從返回時(shí)被叫醒時(shí),線程被放入鎖池,與其他線程競爭重新獲得鎖。 本文探討Java并發(fā)中的其它問題:線程安全、可見性、活躍性等等。 在行文之前,我想先推薦以下兩份資料,質(zhì)量很高:極客學(xué)院-Java并發(fā)編程讀書筆記-《Java并發(fā)編程實(shí)戰(zhàn)》 線程安全 《Java并發(fā)編程實(shí)戰(zhàn)》中提到了太多的術(shù)語...

    NickZhou 評(píng)論0 收藏0
  • 出場(chǎng)率比較高的一道多線程安全面試題

    摘要:程序正常運(yùn)行,輸出了預(yù)期容量的大小這是正常運(yùn)行結(jié)果,未發(fā)生多線程安全問題,但這是不確定性的,不是每次都會(huì)達(dá)到正常預(yù)期的。另外,像等都有類似多線程安全問題,在多線程并發(fā)環(huán)境下避免使用這種集合。 這個(gè)問題是 Java 程序員面試經(jīng)常會(huì)遇到的吧。 工作一兩年的應(yīng)該都知道 ArrayList 是線程不安全的,要使用線程安全的就使用 Vector,這也是各種 Java 面試寶典里面所提及的,可能...

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

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

0條評(píng)論

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