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

資訊專欄INFORMATION COLUMN

「Java并發(fā)編程實戰(zhàn)」之對象的共享

phodal / 3434人閱讀

摘要:當某個不應該發(fā)布的對象被發(fā)布時,這種情況被稱為逸出。線程安全共享線程安全的對象在其內(nèi)部實現(xiàn)同步,因此多線程可以通過對象的公有接口來進行訪問而不需要進一步的同步。

前言

  本系列博客是對《Java并發(fā)編程實戰(zhàn)》的一點總結(jié),本篇主要講解以下幾個內(nèi)容,內(nèi)容會比較枯燥??赡艽蠹铱礃祟}不能能直觀的感受出到底什么意思,這就是專業(yè)術(shù)語,哈哈,解釋下,術(shù)語(terminology)是在特定學科領域用來表示概念的稱謂的集合,在我國又稱為名詞或科技名詞(不同于語法學中的名詞)。術(shù)語是通過語音或文字來表達或限定科學概念的約定性語言符號,是思想和認識交流的工具。我就用白話文來給大家解釋下這些術(shù)語。

線程安全

  什么是線程安全?這算是老生常談的問題了,相信大家在面試的過程中也遇到過,在線程安全的定義中,最核心的概念就是正確性,如果對線程安全性的定義是模糊的,那么就是缺乏對正確性的清晰定義。正確性的含義是,某個類的行為與其規(guī)范完全一致,在良好的規(guī)范中通常會定義各種不變性條件來約束對象的狀態(tài),以及定義各種后驗條件來描述對象操作的結(jié)果。說白了就是一個類無論是在單線程環(huán)境還是多線程環(huán)境中都能正確的執(zhí)行,那么這個類就是線程安全的。如果在線程交替執(zhí)行的過程中導致不可預料的結(jié)果,那么就是線程不安全的。

可見性

  假如有一個變量,現(xiàn)在對它進行讀寫操作,可見性說的就是當前線程對變量的寫操作是否對其它線程可見,就是其它線程能不能知道你對這個變量做了修改。如果不能保證可見,必須使用同步機制。否則當其他線程來讀這個變量的時候,可能會得到一個已經(jīng)失效的值。這個值就被稱為失效數(shù)據(jù)。
  
  在這里提醒大家,對于非volatile類型的long和double變量JVM允許將64位的讀操作或?qū)懖僮鞣纸鉃閮蓚€32位的操作,當讀一個非volatile類型的long變量時,如果讀寫操作是在不同的線程中執(zhí)行,那么很可能會讀取到某個值的高32位和另一個值的低32位,所以在多線程環(huán)境中使用共享可變的long和double等類型的變量時不安全的,除非使用關(guān)鍵字volatile來聲明它們,或者用鎖保護起來。
1.現(xiàn)在來介紹一下Volatile:
Java語言提供了一種稍弱的同步機制,即volatile類型,用來確保將變量的更新操作通知到其他線程。使用就是在變量前面加上volatile即可。在 JMM 中,線程之間的通信采用共享內(nèi)存來實現(xiàn)的。volatile 的內(nèi)存語義是:

當寫一個 volatile 變量時,JMM 會把該線程對應的本地內(nèi)存中的共享變量值,立即刷新到主內(nèi)存中。

當讀一個 volatile 變量時,JMM 會把該線程對應的本地內(nèi)存設置為無效,直接從主內(nèi)存中讀取共享變量。

2.volatile的使用條件:

對變量的寫入操作不依賴變量的當前值,或者你能確保只有單個線程更新變量的值。

該變量不會與其他狀態(tài)變量一起納入不變性條件中。

在訪問變量時不需要加鎖。

加鎖機制既可以確??梢娦杂挚梢源_保原子性,而volatile變量只能確保可見性,千萬不要用它來確保原子性操作。

發(fā)布與逸出

發(fā)布一個對象的意思就是使對象能夠在當前作用域之外的代碼中使用,例如,將一個指向該對象的的引用保存到其他代碼可以訪問的地方,或者在某一個非私有的方法中返回該引用,或者將引用傳遞到其他類方法中。當某個不應該發(fā)布的對象被發(fā)布時,這種情況被稱為逸出。

線程封閉

當訪問共享的可變數(shù)據(jù)時,通常需要使用同步。一種避免使用同步的方式就是不同享數(shù)據(jù),如果僅在單線程內(nèi)訪問數(shù)據(jù),就不需要同步,這種技術(shù)被稱為線程封閉,它是實現(xiàn)線程安全性最簡單的方法之一。下面介紹幾種線程封閉技術(shù)。
1.Ad-hoc線程封閉
Ad-hoc線程封閉是指,維護線程封閉性的職責完全有程序?qū)崿F(xiàn)來承擔。例如可見性修飾符或局部變量,能將對象封閉到目標線程上。事實上對于線程封閉對象通常保存在共有變量中。Ad-hoc線程封閉是非常脆弱的,所以程序中盡量少使用它,可以使用以下兩種技術(shù)(棧封閉,ThreadLocal)。
2.棧封閉
棧封閉也被成為線程內(nèi)部使用或者線程局部使用,不要與ThredaLocal混淆,比Ad-hoc更易于維護,也更加健壯。在棧封閉中,只能通過局部變量才能訪問對象。

//偽代碼
public void test(){
//定義一個變量
Set set ;
// 實例化一個TreeSet對象,并將該對象的一個引用保存到set中。
set = new TreeSet();
}

這樣TreeSet對象就被封閉在局部變量中,因此也被封閉到執(zhí)行線程中,它位于執(zhí)行線程的棧中,其他線程無法訪問這個棧。
3.ThreadLocal
維持線程封閉性的一種更為規(guī)范的方法是使用ThreadLocal,這個類能使線程中的某個值與保存值的對像關(guān)聯(lián)起來,ThreadLocal提供了get與set等訪問接口或方法,這些方法為每個使用該變量的線程都存有一份獨立的副本,因此get總是返回由當前線程執(zhí)行set時設置的最新值。ThreadLocal通常用于防止對可變對像的單實例變量或全局變量進行共享。

   //保存一個數(shù)據(jù)庫連接對像
   public static ThreadLocal connectionThreadLocal = 
   new ThreadLocal(){
       @Override
       protected Connection initialValue() {
           return DriverManager.getConnection(DB_URl);
       }
   };
   //每個線程使用時直接get
   public static Connection getConnection(){
       return connectionThreadLocal.get();
   }
不變性

如果某個對像在被創(chuàng)建之后其狀態(tài)就不能被修改,那么這個對象就是不可變對象,線程安全性是是不可變對象的固有屬性之一。當滿足一下條件時,對象才是不可變的:

對象創(chuàng)建后其狀態(tài)就不能修改。

對象的所有域都是final類型。

對象是正確創(chuàng)建的(在對象的創(chuàng)建期間,this引用沒有逸出)

Final域:
用于構(gòu)造不可變對象。final類型的域是不能修改的(但如果final域所引用的對象是可變的,那么這些引用的對象是可以修改的)。然而在java內(nèi)存模型中,final域還有著特殊的語義。final域能確保初始化過程的安全性,從而可以不受限制的訪問不可變對象,并在共享這些對象時無須同步。

安全發(fā)布

1.要安全發(fā)布一個對象,對象的引用以及對象的狀態(tài)必須同時對其他線程可見,一個正確構(gòu)造的對象可以通過以下方式來安全的發(fā)布:

在靜態(tài)初始化函數(shù)中初始化一個對象引用。

將對象的引用保存到volatile類型的域或者Atomicreferance對象中。

將對象的引用保存到某個正確構(gòu)造對象的final類型域中。

將對象的引用保存到一個由鎖保護的域中。

2.在并發(fā)程序中使用和共享對象時,可以使用一些實用的策略:

線程封閉:線程封閉的對象只能由一個線程擁有,對象被封閉在該線程中,并且只能由這個線程修改

只讀共享:在沒有額外同步的情況下,共享的只讀對象可以由多個線程并發(fā)訪問,但任何線程都不能修改它,共享的只讀對象包括不可變對象和事實不可變對象。

線程安全共享:線程安全的對象在其內(nèi)部實現(xiàn)同步,因此多線程可以通過對象的公有接口來進行訪問而不需要進一步的同步。

保護對象:被保護的對象只能通過持有特定的鎖來訪問,保護對象包括封裝在其他線程安全對象中的對象,以及已發(fā)布的并且由某個特定鎖保護的對象。

大家看后辛苦點個贊點個關(guān)注哦!查看個人主頁,有更多的博客哦。如有錯誤,煩請指正。
有興趣加群一起交流。

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

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

相關(guān)文章

  • Java并發(fā)編程實戰(zhàn)》讀書筆記-第1章 簡介

    摘要:線程允許同一個進程中同時存在多個程序控制流。線程也被稱為輕量級進程?,F(xiàn)代操作系統(tǒng)中,都是以線程為基本的調(diào)度單位,而不是進程。 并發(fā)簡史 在早期的計算機中不包含操作系統(tǒng),從頭至尾都只執(zhí)行一個程序,并且這個程序能訪問計算機所有資源。操作系統(tǒng)的出現(xiàn)使得計算機每次能運行多個程序,并且不同的程序都在單獨的進程中運行:操作系統(tǒng)為各個獨立執(zhí)行的進程分配內(nèi)存、文件句柄、安全證書等。不同進程之間通過一些...

    zhoutk 評論0 收藏0
  • java并發(fā)編程實戰(zhàn)6】AQS獨占鎖ReentrantLock實現(xiàn)

    摘要:鎖與很好的隔離使用者與實現(xiàn)者所需要關(guān)注的領域。那么這個就是包裝線程并且放入到隊列的過程實現(xiàn)的方法。也證實了就是獲取鎖的線程的節(jié)點。如果發(fā)生異常取消請求,也就是將當前節(jié)點重隊列中移除。 前言 自從JDK1.5后,jdk新增一個并發(fā)工具包java.util.concurrent,提供了一系列的并發(fā)工具類。而今天我們需要學習的是java.util.concurrent.lock也就是它下面的...

    sixleaves 評論0 收藏0
  • Java 并發(fā)編程系列帶你了解多線程

    摘要:的內(nèi)置鎖是一種互斥鎖,意味著最多只有一個線程能持有這種鎖。使用方式如下使用顯示鎖之前,解決多線程共享對象訪問的機制只有和。后面會陸續(xù)的補充并發(fā)編程系列的文章。 早期的計算機不包含操作系統(tǒng),它們從頭到尾執(zhí)行一個程序,這個程序可以訪問計算機中的所有資源。在這種情況下,每次都只能運行一個程序,對于昂貴的計算機資源來說是一種嚴重的浪費。 操作系統(tǒng)出現(xiàn)后,計算機可以運行多個程序,不同的程序在單獨...

    Elle 評論0 收藏0
  • <java并發(fā)編程實戰(zhàn)>學習三

    摘要:線程封閉當訪問共享的可變數(shù)據(jù)時,通常需要使用同步。如果僅在單線程內(nèi)訪問數(shù)據(jù),就不要同步。這種技術(shù)成為線程封閉。棧封閉棧封閉是線程封閉的一種特例,在棧封閉中,只能通過局部變量才能訪問對象。,對象是正確創(chuàng)建的。 線程封閉 當訪問共享的可變數(shù)據(jù)時,通常需要使用同步。一種避免使用同步的方式就是不共享數(shù)據(jù)。如果僅在單線程內(nèi)訪問數(shù)據(jù),就不要同步。這種技術(shù)成為線程封閉(Thread Confine...

    Richard_Gao 評論0 收藏0
  • 【J2SE】java并發(fā)編程實戰(zhàn) 讀書筆記( 一、二、三章)

    摘要:發(fā)布的對象內(nèi)部狀態(tài)可能會破壞封裝性,使程序難以維持不變性條件。不變性線程安全性是不可變對象的固有屬性之一??勺儗ο蟊仨毻ㄟ^安全方式來發(fā)布,并且必須是線程安全的或者有某個鎖保護起來。 線程的優(yōu)缺點 線程是系統(tǒng)調(diào)度的基本單位。線程如果使用得當,可以有效地降低程序的開發(fā)和維護等成本,同時提升復雜應用程序的性能。多線程程序可以通過提高處理器資源的利用率來提升系統(tǒng)的吞吐率。與此同時,在線程的使用...

    QLQ 評論0 收藏0

發(fā)表評論

0條評論

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