国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

第2章-對象的共享

2019-11-10 17:18:51
字體:
供稿:網(wǎng)友

1.分析清單3-1 2.syn是否禁止指令重排序 3.volatile修飾引用類型 4.java中的不變性條件指什么

要編寫正確的并發(fā)程序,關(guān)鍵問題在于:在訪問共享的可變狀態(tài)時(shí)進(jìn)行正確的管理。

第二章介紹了如何通過避免多個(gè)線程在同一時(shí)刻訪問相同的數(shù)據(jù),而本章將介紹如何共享和發(fā)布對象,從而使他們能夠安全地由多個(gè)線程同時(shí)訪問。

synchronized 1.原子性 2.內(nèi)存可見性(memory visibility)3.互斥性

在沒有同步的情況下,編譯器處理器以及運(yùn)行時(shí)等都可能對操作的執(zhí)行順序進(jìn)行一些意想不到的調(diào)整。在缺乏足夠同步多線程程序中,要想對內(nèi)存操作的執(zhí)行順序進(jìn)行判斷,幾乎無法得出正確結(jié)論。

在缺乏同步的程序中,可能會出現(xiàn)一種產(chǎn)生錯(cuò)誤結(jié)果的情況:失效數(shù)據(jù)

出現(xiàn)失效數(shù)據(jù)的可能 :

不能保證原子性不能保證可見性存在指令重排序

失效數(shù)據(jù)可能會導(dǎo)致一些嚴(yán)重的安全問題或者活躍性問題,比如

輸出錯(cuò)誤的值使程序無法結(jié)束,無限循環(huán)意料之外的異常被破壞的數(shù)據(jù)結(jié)構(gòu)不精確的計(jì)算

當(dāng)線程在沒有同步的情況下讀取變量時(shí),可能會得到一個(gè)失效值,但至少這個(gè)值是由之前某個(gè)線程設(shè)置的值,而不是一個(gè)隨機(jī)值,這種安全性保證也被稱為最低安全性(out-of-thin-airsafety)

最低安全性適用于絕大多數(shù)變量,但是存在一個(gè)例外:非volatile類型的64位數(shù)值變量(double和long)。java內(nèi)存模型要求,變量的讀取操作和寫入操作都必須是原子操作,但對于非volatile類型的long和double變量,jvm允許將64位的讀操作或?qū)懖僮鞣纸鉃閮蓚€(gè)32位的操作。當(dāng)讀取一個(gè)非volatile類型的long變量時(shí),如果對該變量的讀操作和寫操作在不同的線程中執(zhí)行,那么很可能會讀取到某個(gè)值的高32位和另一個(gè)值的低32位。因此,即使不考慮失效數(shù)據(jù),在多線程程序中使用共享且可變的long和double等類型變量也是不安全的,(這里是指既保證不了最低安全性,也保證不了原子性 。。。)除非

用關(guān)鍵字volatile來聲明它們用鎖保護(hù)起來

內(nèi)置鎖可以用于確保某個(gè)線程以一種可預(yù)測的方式來查看另一個(gè)線程的執(zhí)行情況

java語言提供了一種稍弱的同步機(jī)制,即volatile變量,用來確保將變量的更新操作通知到其他線程。當(dāng)把變量聲明為volatile類型后,編譯器與運(yùn)行時(shí)都會注意到這個(gè)變量是共享的,(因此不能將局部變量聲明為volatile)因此不會將該變量上的操作與其他內(nèi)存操作一起重排序。volatile變量不會緩存在寄存器或者對其他處理器不可見的地方,因此在讀取volatile類型變量時(shí)總會返回最新的值

在訪問volatile變量時(shí)不會執(zhí)行加鎖操作,因此也就不會使執(zhí)行線程阻塞,因此volatile變量是一種比synchronized關(guān)鍵字更輕量級的同步機(jī)制。

在當(dāng)前大多數(shù)處理器架構(gòu)上,讀取volatile變量的開銷只比讀取非volatile變量的開銷略高一些。

volatile變量的正確使用方式包括:

確保他們自身狀態(tài)的可見性確保他們所引用對象狀態(tài)的可見性標(biāo)識一些重要的程序生命周期事件的發(fā)生(例如,初始化或關(guān)閉)

volatile變量通常用作某個(gè)操作完成、發(fā)生中斷或者狀態(tài)的標(biāo)志

volatile的語義不足以確保遞增操作(count++)的原子性,除非你能確保只有一個(gè)線程對變量執(zhí)行 操作

當(dāng)且僅當(dāng)滿足以下所有條件時(shí),才應(yīng)該使用volatile變量:

對變量的寫入操作不依賴變量的當(dāng)前值,或者你能確保只有單個(gè)線程更新變量的值。該變量不會與其他狀態(tài)變量一起納入不變性條件中。在訪問變量時(shí)不需要加鎖

發(fā)布(Publish)一個(gè)對象的意思是指,使對象能夠在當(dāng)前作用域之外的代碼中使用。比如:

將一個(gè)指向該對象的引用保存到其他代碼可以訪問的地方(公有靜態(tài)變量)在某一個(gè)私有的方法中返回改引用將引用傳遞到其他類的方法中(方法傳遞,即alien方法,發(fā)布一個(gè)內(nèi)部類的實(shí)例)

在許多情況中,我們要確保對象及其內(nèi)部狀態(tài)不被發(fā)布。而在某些情況下,我們又需要發(fā)布某個(gè)對象,但如果發(fā)布時(shí)要確保線程安全性,則可能需要同步。發(fā)布內(nèi)部狀態(tài)可能會破壞封裝行,并且使程序難以維持不變性條件。如果在對象構(gòu)造完成之前就發(fā)布該對象,就會破壞線程安全性

當(dāng)某個(gè)不應(yīng)該發(fā)布的對象被發(fā)布時(shí),這種情況就被稱為逸出(Escape)。

當(dāng)發(fā)布某個(gè)對象時(shí),可能會間接地發(fā)布其他對象。

當(dāng)發(fā)布一個(gè)對象時(shí),在該對象的非私有域中引用的所有對象同樣會被發(fā)布。

假定有一個(gè)類C,對于C來說,“外部方法(alien)” 是指行為并不完全由C來規(guī)定的方法,包括

其他類中定義的方法類C中可以被改寫的方法(既不是私有方法也不是final方法)

當(dāng)把一個(gè)對象傳遞給某個(gè)外部方法時(shí),就相當(dāng)于發(fā)布了這個(gè)對象。

發(fā)布內(nèi)部類實(shí)例時(shí),也隱含地發(fā)布了外部類實(shí)例本身,因?yàn)樵谶@個(gè)內(nèi)部類的實(shí)例中包含了外部類實(shí)例的隱含引用。

不安全(正確)的對象構(gòu)造過程有可能導(dǎo)致this逸出,比如

在構(gòu)造函數(shù)中發(fā)布一個(gè)匿名內(nèi)部類在構(gòu)造函數(shù)中啟動(dòng)一個(gè)線程在構(gòu)造函數(shù)中調(diào)用一個(gè)可改寫的實(shí)例方法(alien方法)
發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 平乐县| 银川市| 泸水县| 紫阳县| 牟定县| 海门市| 镶黄旗| 南澳县| 信宜市| 涿鹿县| 灌云县| 航空| 盐边县| 汨罗市| 闸北区| 砚山县| 全南县| 汶川县| 嘉祥县| 德保县| 镇平县| 冀州市| 福清市| 广宁县| 蓬莱市| 天峨县| 罗源县| 洞头县| 大同市| 长宁县| 英山县| 安吉县| 贵港市| 正安县| 鄂伦春自治旗| 板桥市| 山阴县| 古浪县| 清原| 攀枝花市| 高雄县|