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

資訊專欄INFORMATION COLUMN

【Java并發】線程安全性

劉玉平 / 2253人閱讀

摘要:另一個是使用鎖的機制來處理線程之間的原子性。依賴于去實現鎖,因此在這個關鍵字作用對象的作用范圍內,都是同一時刻只能有一個線程對其進行操作的。

線程安全性

定義:當多個線程訪問某個類時,不管運行時環境采用何種調度方式或者這些線程將如何交替執行,并且在主調代碼中不需要任何額外的同步或協同,這個類都能表現出正確的行為,那么就稱這個類是線程安全的。

線程安全性主要體現在三個方面:原子性、可見性、有序性:

原子性:提供了互斥訪問,同一時刻只能有一個線程來對它進行操作

可見性:一個線程對主內存的修改可以及時地被其他線程觀察到

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

原子性

原子性在 JDK 中主要由兩個方面體現出來:

Atomic

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

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

synchronized

依賴于 JVM 去實現鎖,因此在這個關鍵字作用對象的作用范圍內,都是同一時刻只能有一個線程對其進行操作的。synchronized 是 Java 中的一個關鍵字,是一種同步鎖。它可以修飾的對象主要有四種:

修飾代碼塊:大括號括起來的代碼,作用于調用的對象

修飾方法:整個方法,作用于調用的對象

修飾靜態方法:整個靜態方法,作用于所有對象

修飾類:括號括起來的部分,作用于所有對象

注意:如果當前類是一個父類,子類調用父類的被 synchronized 修飾的方法,不會攜帶 synchronized 屬性,因為 synchronized 不屬于方法聲明的一部分。
Lock

首先要說明的就是 Lock,通過查看 Lock 的源碼可知,Lock 是一個接口。ReentrantLock 是唯一實現了 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 默認情況下非公平鎖,可設置為公平鎖

讀寫鎖

ReadWriteLock / ReentrantReadWriteLock

可見性

導致共享變量在線程間不可見的原因:

線程交叉執行

重排序結合線程交叉執行

共享變量更新后的值沒有在工作內存與主存間及時更新

JVM 對于可見性,提供了 synchronized 和 volatile:

synchronized

JMM 關于 synchronized 的兩條規定:

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

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

volatile

volatile 的方式是:通過加入內存屏障禁止重排序優化來實現。

對 volatile 變量寫操作時,會在寫操作后加入一條 store 屏障指令,將本地內存中的共享變量值刷新到主內存。

對 volatile 變量讀操作時,會在讀操作前加入一條 load 屏障指令,從主內存中讀取共享變量。

volatile的屏障操作都是 cpu 級別的;適合狀態驗證,不適合累加值,volatile關鍵字不具有原子性。

適合狀態驗證,不適合累加值,volatile關鍵字不具有原子性

有序性

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

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

【以下規則摘抄自《深入理解Java虛擬機》】

程序次序規則:一個線程內,按照代碼順序,書寫在前面的操作先行發生于書寫在后面的操作

鎖定規則:一個unlock操作先行發生于后面對同一個鎖的lock操作

volatile變量規則:對一個變量的寫操作先行發生于后面對這個變量的讀操作(重要)

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

線程啟動規則:Thread對象的start()方法先行發生于此線程的每一個動作

線程中斷規則:對線程interrupt()方法的調用先行發生于被中斷線程的代碼檢測到中斷事件的發生

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

思維導圖

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

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

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

相關文章

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

    摘要:并發模塊本身有兩種不同的類型進程和線程,兩個基本的執行單元。調用以啟動新線程。在大多數系統中,時間片發生不可預知的和非確定性的,這意味著線程可能隨時暫停或恢復。 大綱 什么是并發編程?進程,線程和時間片交織和競爭條件線程安全 策略1:監禁 策略2:不可變性 策略3:使用線程安全數據類型 策略4:鎖定和同步 如何做安全論證總結 什么是并發編程? 并發并發性:多個計算同時發生。 在現代...

    instein 評論0 收藏0
  • [Java并發-11] 并發容器的使用

    摘要:同步容器及其注意事項中的容器主要可以分為四個大類,分別是和,但并不是所有的容器都是線程安全的。并發容器及其注意事項在版本之前所謂的線程安全的容器,主要指的就是同步容器,當然因為所有方法都用來保證互斥,串行度太高了,性能太差了。 Java 并發包有很大一部分內容都是關于并發容器的,因此學習和搞懂這部分的內容很有必要。 Java 1.5 之前提供的同步容器雖然也能保證線程安全,但是性能很差...

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

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

    fuyi501 評論0 收藏0
  • Java并發編程筆記(二)

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

    NickZhou 評論0 收藏0
  • 出場率比較高的一道多線程安全面試題

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

    xiyang 評論0 收藏0

發表評論

0條評論

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