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

資訊專欄INFORMATION COLUMN

JVM筆記-13

cyixlq / 596人閱讀

摘要:不可變?nèi)缃^對線程安全就是滿足并發(fā)編程實戰(zhàn)中對線程安全的定義在中標注自己是線程安全的類,大都不是絕對的線程安全。如的和二實現(xiàn)線程安全的方法互斥同步互斥是因同步是果互斥是方法同步是目的。

一.到底什么叫線程安全:
java并發(fā)編程實戰(zhàn)中對線程安全的定義是:當多個線程訪問一個對象時,如果不用考慮這些線程在運行時環(huán)境下的調(diào)度和交替執(zhí)行,也不需要進行額外的同步,或者在調(diào)用方進行任何其他的協(xié)調(diào)操作,調(diào)用這個對象的行為都可以獲得正確的結(jié)果,那這個對象是線程安全的”。這個定義比較嚴格,一般我們都會將其弱化。
按照線程安全的“安全程度”由強至弱來排序,我們可以將Java語言中各種操作共享的數(shù)據(jù)分為以下5類:不可變、絕對線程安全、相對線程安全、線程兼容和線程對立。
1.不可變:如String
2.絕對線程安全就是滿足java并發(fā)編程實戰(zhàn)中對線程安全的定義
在javaAPI中標注自己是線程安全的類,大都不是絕對的線程安全。如Vector,它的add,get,size方法都加了synchronized修飾的,但請看下面一段代碼:

private static Vector vector = new Vector();  
  
  
    public static void main(String[] args) {  
        while (true) {  
            for (int i = 0; i < 10; i++) {  
                vector.add(i);  
            }  
  
  
            Thread removeThread = new Thread(new Runnable() {  
                @Override  
                public void run() {  
                    for (int i = 0; i < vector.size(); i++) {  
                        vector.remove(i);  
                    }  
                }  
            });  
  
  
            Thread printThread = new Thread(new Runnable() {  
                @Override  
                public void run() {  
                    for (int i = 0; i < vector.size(); i++) {  
                        System.out.println((vector.get(i)));  
                    }  
                }  
            });  
  
  
            removeThread.start();  
            printThread.start();  
  
  
            //不要同時產(chǎn)生過多的線程,否則會導致操作系統(tǒng)假死  
            while (Thread.activeCount() > 20);  
        }  
    }  

這段代碼有可能產(chǎn)生問題,因為如果在printThread剛好要打印最后一個元素時removeThread恰好刪除了一個元素,則printThread就會產(chǎn)生ArrayIndexOutOfBoundsException

3.相對線程安全
相對的線程安全就是我們通常意義上所講的線程安全,它需要保證對這個對象多帶帶的操作是線程安全的,我們在調(diào)用的時候不需要做額外的保障措施,但是對于一些特定順序的連續(xù)調(diào)用,就可能需要在調(diào)用端使用額外的同步手段來保證調(diào)用的正確性。如上面的Vector容器就是相對線程安全

4.線程兼容
線程兼容是指對象本身并不是線程安全的,但是可以通過在調(diào)用端正確地使用同步手段來保證對象在并發(fā)環(huán)境中可以安全地使用,我們平常說一個類不是線程安全的,絕大多數(shù)時候指的是這一種情況

5.線程對立
指的是指無論調(diào)用端是否采取了同步措施,都無法在多線程環(huán)境中并發(fā)使用的代碼。如Thread的suspend()和resume()

二.實現(xiàn)線程安全的方法
1.互斥同步
互斥是因,同步是果;互斥是方法,同步是目的。
在Java中,最基本的互斥同步手段就是synchronized關鍵字,synchronized關鍵字經(jīng)過編譯之后,會在同步塊的前后分別形成monitorenter和monitorexit這兩個字節(jié)碼指令,這兩個字節(jié)碼都需要一個reference類型的參數(shù)來指明要鎖定和解鎖的對象。
synchronized同步塊對同一條線程來說是可重入的,不會出現(xiàn)自己把自己鎖死的問題。

2.非阻塞同步
互斥同步也叫阻塞同步。阻塞同步屬于一種悲觀的并發(fā)策略,在有可能出現(xiàn)并發(fā)問題的地方都要進行同步措施(如加鎖)。非阻塞同步采用樂觀的并發(fā)策略,通過沖突檢測檢查是否有競爭,有的進行補償措施(如不斷重試直到成功),因為他不用把線程掛起所以是非阻塞的??墒沁@就好了嗎,要知道我們肯定要保證沖突檢測和操作這兩個操作的原子性啊,那怎么保證呢,肯定不能用互斥同步(這樣的話還是變成會阻塞的),答案是必須要有硬件指令集的支持來保證原子性。
這類常用指令有:
測試并設置(Test-and-Set)。
獲取并增加(Fetch-and-Increment)。
交換(Swap)。
比較并交換(Compare-and-Swap,下文稱CAS)。
加載鏈接/條件存儲(Load-Linked/Store-Conditional,下文稱LL/SC)。

Java中的CAS操作由sun.misc.Unsafe類里面的compareAndSwapInt()和compareAndSwapLong()等幾個方法包裝提供,虛擬機在內(nèi)部對這些方法做了特殊處理,即時編譯出來的結(jié)果就是一條平臺相關的處理器CAS指令,沒有方法調(diào)用的過程,或者可以認為是無條件內(nèi)聯(lián)進去了。
由于Unsafe類不是提供給用戶程序調(diào)用的類(Unsafe.getUnsafe()的代碼中限制了只有啟動類加載器(Bootstrap ClassLoader)加載的Class才能訪問它),因此,如果不采用反射手段,我們只能通過其他的JavaAPI來間接使用它,如J.U.C包里面的整數(shù)原子類,其中的compareAndSet()和getAndIncrement()等方法都使用了Unsafe類的CAS操作。

無同步方案
有些代碼不涉及共享數(shù)據(jù),當然就不需要同步了。

三.鎖優(yōu)化
1.自旋鎖與自適應自旋
自旋就是獲取鎖失敗的時候讓線程忙循環(huán),而不是阻塞,這可以提高響應速度以及避免線程切換的開銷,但浪費CPU時間。
自適應自旋就是如果循環(huán)獲取一定次數(shù)還沒獲取成功,就阻塞。
自旋鎖在JDK中默認關閉,可使用用-XX:+UseSpinning開啟

2.鎖消除
鎖消除是指虛擬機即時編譯器在運行時,對一些代碼上要求同步,但是被檢測到不可能存在共享數(shù)據(jù)競爭的鎖進行消除。鎖消除的主要判定依據(jù)來源于逃逸分析的數(shù)據(jù)支持,如果判斷在一段代碼中,堆上的所有數(shù)據(jù)都不會逃逸出去從章已經(jīng)講解過逃逸分析技術(shù)),如果判斷在一段代碼中,堆上的所有數(shù)據(jù)都不會逃逸出去從而被其他線程訪問到,那就可以把它們當做棧上數(shù)據(jù)對待,認為它們是線程私有的,同步加鎖自然就無須進行。
3.鎖粗化
防止過于頻繁的加鎖解鎖操作

4.輕量級鎖

在代碼進入同步塊的時候,如果此同步對象沒有被鎖定(鎖標志位為“01”狀態(tài)),虛擬機首先將在當前線程的棧幀中建立一個名為鎖記錄(Lock Record)的空間,用于存儲鎖對象目前的Mark Word的拷貝(官方叫Displaced Mark Word)。

5.偏向鎖
偏向鎖優(yōu)化點加解鎖在于連CAS操作都不用了

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

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

相關文章

  • 《深入理解JVM虛擬機》讀書筆記-開篇

    摘要:年開始工作,年畢業(yè),兩年來的工作接觸知識面很廣,用的東西比較多,包括基礎的開發(fā)到開發(fā)到大數(shù)據(jù),推薦系統(tǒng),到服務器運維,到數(shù)據(jù)庫維護,,,可愈發(fā)明白貪多嚼不爛的道理,唯有才能踏踏實實,趁著剛剛讀完這本書,想復習,順便寫一些筆記,聊以鞏固。 13年開始工作,14年畢業(yè),兩年來的工作接觸知識面很廣,用的東西比較多,包括基礎的java開發(fā)到j2ee,web開發(fā),到大數(shù)據(jù),推薦系統(tǒng),到服務器運維...

    legendaryedu 評論0 收藏0
  • 13張圖解就能讓女朋友徹底了解Java中的內(nèi)存模型,快上車!

    摘要:前言了解中的對象變量等存放的內(nèi)存區(qū)域十分重要本文將全面講解虛擬機中的內(nèi)存模型分區(qū),希望你們會喜歡目錄張圖解就能讓女朋友徹底了解中的內(nèi)存模型,快上車虛擬機 前言了解Java中的對象、變量等存放的內(nèi)存區(qū)域十分重要本文將全面講解Java虛擬機中的內(nèi)存模型 & 分區(qū),希望你們會喜歡目錄1、內(nèi)存模型 & 分區(qū)Java虛擬機在運行Ja...

    番茄西紅柿 評論0 收藏2637
  • Java學習路線總結(jié),搬磚工逆襲Java架構(gòu)師(全網(wǎng)最強)

    摘要:哪吒社區(qū)技能樹打卡打卡貼函數(shù)式接口簡介領域優(yōu)質(zhì)創(chuàng)作者哪吒公眾號作者架構(gòu)師奮斗者掃描主頁左側(cè)二維碼,加入群聊,一起學習一起進步歡迎點贊收藏留言前情提要無意間聽到領導們的談話,現(xiàn)在公司的現(xiàn)狀是碼農(nóng)太多,但能獨立帶隊的人太少,簡而言之,不缺干 ? 哪吒社區(qū)Java技能樹打卡?【打卡貼 day2...

    Scorpion 評論0 收藏0
  • 那些年我看過的書 —— 致敬我的大學生活 —— Say Good Bye !

    摘要:開頭正式開啟我入職的里程,現(xiàn)在已是工作了一個星期了,這個星期算是我入職的過渡期,算是知道了學校生活和工作的差距了,總之,盡快習慣這種生活吧。當時是看的廖雪峰的博客自己也用做爬蟲寫過幾篇博客,不過有些是在前人的基礎上寫的。 showImg(https://segmentfault.com/img/remote/1460000010867984); 開頭 2017.08.21 正式開啟我...

    xiaoqibTn 評論0 收藏0

發(fā)表評論

0條評論

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