<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    kxbin
    成功留給有準備的人
    posts - 10,  comments - 35,  trackbacks - 0

    在寫Java程序的時候,何時需要進行并發控制,關鍵在于判斷這段程序或這個類是否是線程安全的。

    當多個線程訪問一個類時,如果不用考慮這些線程在運行時環境下的調度和交替執行,并且不需要額外的同步,這個類的行為仍然是正確的,那么稱這個類是線程安全的。我們設計類就是要在有潛在并發問題存在情況下,設計線程安全的類。線程安全的類可以通過以下手段來滿足:

    • 不跨線程共享變量
    • 使狀態變量為不可變的
    • 在任何訪問狀態變量的時候使用同步。
    • 每個共享的可變變量都需要由唯一一個確定的鎖保護。

    滿足線程安全的一些思路

    1)從源頭避免并發問題

    很多開發者一想到有并發的可能就通過底層技術來解決問題,其實往往可以通過上層的架構設計和業務分析來避免并發場景。比如我們需要用多線程或分布式集群來計算一堆客戶的相關統計值,由于客戶的統計值是共享數據,因此會有并發潛在可能。但從業務上我們可以分析出客戶與客戶之間數據是不共享的,因此可以設計一個規則來保證一個客戶的計算工作和數據訪問只會被一個線程或一臺工作機完成,而不是把一個客戶的計算工作分配給多個線程去完成。這種規則很容易設計。當你從源頭就避免了并發問題的可能,下面的工作就完全可以不用擔心線程安全問題。

    2)無狀態就是線程安全

    多線程編程或者分布式編程最忌諱有狀態,一有狀態就不但限制了其橫向擴展能力,也是產生并發問題的起源。當你設計的類是無狀態的,那么它永遠都是線程安全的。因此在設計階段需要考慮如何用無狀態的類來滿足你的業務需求

    3)分清原子性操作和復合操作

    所謂原子性,是說一個操作不會被其他線程打斷,能保證其從開始到結束獨享資源連續執行完這一操作。如果所有程序塊都是原子性的,那么就不存在任何并發問題。而很多看上去像是原子性的操作正式并發問題高災區。比如所熟知的計數器(count++)和check-then-act,這些都是很容易被忽視的,例如大家所常用的惰性初始化模式,以下代碼就不是線程安全的:

     

    1. @NotThreadSafe  
    2. public class LazyInitRace {  
    3.     private ExpensiveObject instance = null;  
    4.     public ExpensiveObject getInstance() {  
    5.         if (instance == null)  
    6.             instance = new ExpensiveObject();  
    7.         return instance;  
    8.     }  
    9. }  

     

    這段代碼具體問題在于沒有認識到if(instance==null)和instance = new ExpensiveObject();是兩條語句,放在一起就不是原子性的,就有可能當一個線程執行完if(instance==null)后會被中斷,另一個線程也去執行if(instance==null),這次兩個線程都會執行后面的instance = new ExpensiveObject();這也是這個程序所不希望發生的。

    雖然check-then-act從表面上看很簡單,但卻普遍存在與我們日常的開發中,特別是在數據庫存取這一塊。比如我們需要在數據庫里存一個客戶的統計值,當統計值不存在時初始化,當存在時就去更新。如果不把這組邏輯設計為原子性的就很有可能產生出兩條這個客戶的統計值。

    在單機環境下處理這個問題還算容易,通過鎖或者同步來把這組復合操作變為原子操作,但在分布式環境下就不適用了。一般情況下是通過在數據庫端做文章,比如通過唯一性索引或者悲觀鎖來保障其數據一致性。當然任何方案都是有代價的,這就需要具體情況下來權衡。

    另外,java1.5以后提供了一套提供原子性操作的類,有興趣的可以研究一下它是如何在軟件層面保證原子性的。

    4)鎖的合理使用

    大家都知道可以用鎖來解決并發問題,但在具體使用上還有很多講究,比如:

    • 每個共享的可變變量都需要由一個個確定的鎖保護。
    • 一旦使用了鎖,就意味著這段代碼的執行就喪失了操作系統多道程序的特性,會在一定程度上影響性能
    • 鎖不能解決在分布式環境共享變量的并發問題
    posted on 2011-10-13 15:37 kxbin 閱讀(281) 評論(0)  編輯  收藏 所屬分類: java基礎
    你恨一個人是因為你愛他;你喜歡一個人,是因為他身上有你沒有的;你討厭一個人是因為他身上有你有的東西;你經常在別人面前批評某人,其實潛意識中是想接近他。

    <2025年5月>
    27282930123
    45678910
    11121314151617
    18192021222324
    25262728293031
    1234567

    常用鏈接

    留言簿(5)

    隨筆檔案

    文章分類

    文章檔案

    相冊

    收藏夾

    J2EE

    java技術網站

    Linux

    平時常去的網站

    數據庫

    電影網站

    網站設計

    搜索

    •  

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 亚洲天堂福利视频| 亚洲av日韩片在线观看| 亚洲午夜久久久精品影院| a视频在线免费观看| 青青草原亚洲视频| 国产成年无码久久久免费| 亚洲精品你懂的在线观看| 久久国产精品国产自线拍免费| 亚洲天堂免费在线视频| 中国性猛交xxxxx免费看| 亚洲乱亚洲乱妇无码麻豆| a级毛片免费完整视频| 亚洲综合日韩中文字幕v在线| 99蜜桃在线观看免费视频网站| 亚洲视频免费一区| 日韩吃奶摸下AA片免费观看| 亚洲欧美日韩久久精品| 免费在线不卡视频| 国产午夜无码精品免费看| 亚洲精品在线免费观看视频| 免费无码肉片在线观看| 国产成人亚洲精品播放器下载| 国产亚洲色视频在线| 免费女人高潮流视频在线观看| 亚洲伊人久久大香线蕉啊| 日本成人免费在线| 99久久99这里只有免费的精品| 久久久久久亚洲AV无码专区| 美女黄网站人色视频免费国产 | 亚洲国产人成在线观看| 成年女人毛片免费观看97| ssswww日本免费网站片| 亚洲人成依人成综合网| 青青青国产免费一夜七次郎| 黄 色一级 成 人网站免费| 亚洲国产精品一区二区久| 免费人成年激情视频在线观看| 国产在线观看免费视频软件| 亚洲综合无码一区二区痴汉| 久久久久久亚洲精品不卡| 国产免费不卡v片在线观看|