Java并發(fā)編程學習記錄#1

線程安全篇A

其實,并發(fā)編程理論并不過多的涉及線程和鎖繁调,雖然構建并發(fā)程序需要正確的使用線程和鎖萨蚕,然而這只是內部機理帶來的手段而已;本質上來說蹄胰,寫出線程安全的程序岳遥,在于狀態(tài)的訪問管理,特別是共享和可變狀態(tài)裕寨。

一個對象的狀態(tài)是其數(shù)據浩蓉,它可以存儲在其實例或者靜態(tài)域中,這些數(shù)據也可以來自其它獨立的實例對象宾袜。對象的狀態(tài)捻艳,包括了那些所有會影響其外部可見行為的數(shù)據。

  • 說到共享庆猫,意思是一個變量可以被多個線程訪問;
  • 說到可變性认轨,意思是一個值可以在其生命周期內被改變。

我們談到線程安全似乎指的是代碼月培,但真正我們要做的是嘁字,保護數(shù)據不被不受控制的訪問影響昨稼。

對象是否需要設置成線程安全,在于其是否需要多線程訪問拳锚,程序如何使用對象假栓,決定了其是否需要線程安全,而不取決于這個對象能做什么霍掺。

Java中同步的一個基本機理是使用synchronized關鍵字匾荆,這能提供一個排它鎖;同時杆烁,同步也包含了volatile關鍵字牙丽,具體鎖以及原子變量。不遵從以上規(guī)則的看似穩(wěn)定的情況兔魂,總是存在一定的隱患烤芦。

多線程訪問可變狀態(tài)時,若沒有適合的同步操作析校,總是存在問題隱患构罗。有三個基本方式可以修復此類問題。

  • 不要在線程間共享可變狀態(tài)
  • 將狀態(tài)設置成不可變
  • 無論何時訪問可變狀態(tài)智玻,都使用同步

設計一個線程安全的類要遠比將類重構成線程安全容易的多咬荷。
面向對象編程的一些技巧可以幫助更容易的創(chuàng)建線程安全類仅叫,比如封裝和數(shù)據隱藏。越少代碼訪問特定的變量,越容易將其同步杆查,越好的封裝喻圃,越容易實現(xiàn)線程安全崔步。

什么是線程安全

線程安全類的定義:當被多線程訪問時菲茬,它總能表現(xiàn)正確,而不管運行環(huán)境下多線程的調度或是線程的交叉執(zhí)行裹驰,并且不需要調用代碼進行額外的同步或其它協(xié)調操作隧熙。線程安全類封裝了一切需要的同步,因此客戶端并不需要自己提供這些邦马。

無狀態(tài)的對象總是線程安全的贱鼻,比如絕大多數(shù)的Servlet對象(Javaweb,例子省略)滋将,它并沒有成員變量邻悬,也沒有其它類成員的引用,它涉及的計算只存在于局部變量中随闽,而局部變量是線程私有的父丰,所以其它線程的操作并不會影響當前線程的計算或狀態(tài),即它是線程安全的。

原子性

原子操作:單一的蛾扇,不可被拆分的操作攘烛,這是相對所有操作而言的,其總是操作在同一個狀態(tài)上镀首。
比如

int i = 0;
++i;//op1

op1并不是一個原子操作坟漱,它是三個子操作的序列:獲取數(shù)據,修改數(shù)據更哄,將數(shù)據寫回芋齿。
這是一個讀-改-寫的操作,在某些場景下成翩,不同步這種操作會引發(fā)線程不安全的問題觅捆,如serlvet中統(tǒng)計訪問數(shù)。

  1. 競爭條件

競爭條件的出現(xiàn):當計算結果的正確性依賴于運行時的相對時間點或是線程的交叉調用麻敌。
最常見的競爭條件類型:檢查-執(zhí)行策略栅炒。這可能造成過期的檢查結果決定下一步的行為。

  • 懶加載中的競爭條件

懶加載指的是直到真正使用一個對象時术羔,才去初始化它赢赊,并只初始化一次。未做同步處理的懶加載容易出現(xiàn)線程安全問題聂示。比如下面這個例子域携。

@NotThreadSafe
public class LazyInitRace {
    private ExpensiveObject instance = null;

    public ExpensiveObject getInstance() {
        if (instance == null)
            instance = new ExpensiveObject();
        return instance;
    }
}

class ExpensiveObject { }

首先,getInstance方法將檢查ExpensiveObject對象是否已經存在鱼喉,若是的話,直接返回實例對象趋观,若否的話扛禽,則創(chuàng)建一個實例返回。但是這里面是會受到競爭條件影響的皱坛。比如编曼,加入有A和B兩個線程同時訪問getInstance,A發(fā)現(xiàn)ExpensiveObject對象為null剩辟,于是開始創(chuàng)建它掐场,此時B也在檢查該對象是否為空,而這個結果是難以預測的贩猎,比如線程如何調度熊户,初始化占用的時間以及給成員instance賦值的時機等。而B檢查的結果吭服,又會帶來getInstance方法返回不同的結果嚷堡。

數(shù)字自增操作和對象懶加載操作都是一系列操作的序列,這會造成競爭條件的發(fā)生艇棕。因此蝌戒,為了避免競爭條件的發(fā)生串塑,這些操作需要一種方式來避免一個正在修改的狀態(tài)被其它線程訪問,即需要保證北苟,當要訪問或修改某個狀態(tài)時桩匪,可以發(fā)生在這個狀態(tài)修改前或是修改后,而不是在修改中友鼻。

其中的一種方式吸祟,就是將讀-改-寫(比如自增操作)以及檢查-執(zhí)行(比如懶加載)的操作變?yōu)樵有缘摹1热缱栽霾僮魈乙疲梢允褂胏oncurrent包中的原子型類AtomicLong屋匕。比如懶加載,可以使用加鎖同步的方式使其能夠被原子性的執(zhí)行借杰。

//待下篇

主要參考自_ Java Concurrency in Practice

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末过吻,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子蔗衡,更是在濱河造成了極大的恐慌纤虽,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,941評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件绞惦,死亡現(xiàn)場離奇詭異逼纸,居然都是意外死亡,警方通過查閱死者的電腦和手機济蝉,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評論 3 395
  • 文/潘曉璐 我一進店門杰刽,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人王滤,你說我怎么就攤上這事贺嫂。” “怎么了雁乡?”我有些...
    開封第一講書人閱讀 165,345評論 0 356
  • 文/不壞的土叔 我叫張陵第喳,是天一觀的道長。 經常有香客問我踱稍,道長曲饱,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,851評論 1 295
  • 正文 為了忘掉前任珠月,我火速辦了婚禮扩淀,結果婚禮上,老公的妹妹穿的比我還像新娘桥温。我一直安慰自己引矩,他們只是感情好,可當我...
    茶點故事閱讀 67,868評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著旺韭,像睡著了一般氛谜。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上区端,一...
    開封第一講書人閱讀 51,688評論 1 305
  • 那天值漫,我揣著相機與錄音,去河邊找鬼织盼。 笑死杨何,一個胖子當著我的面吹牛,可吹牛的內容都是我干的沥邻。 我是一名探鬼主播危虱,決...
    沈念sama閱讀 40,414評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼唐全!你這毒婦竟也來了埃跷?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,319評論 0 276
  • 序言:老撾萬榮一對情侶失蹤邮利,失蹤者是張志新(化名)和其女友劉穎弥雹,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體延届,經...
    沈念sama閱讀 45,775評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡剪勿,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了方庭。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片厕吉。...
    茶點故事閱讀 40,096評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖二鳄,靈堂內的尸體忽然破棺而出赴涵,到底是詐尸還是另有隱情,我是刑警寧澤订讼,帶...
    沈念sama閱讀 35,789評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站扇苞,受9級特大地震影響欺殿,放射性物質發(fā)生泄漏。R本人自食惡果不足惜鳖敷,卻給世界環(huán)境...
    茶點故事閱讀 41,437評論 3 331
  • 文/蒙蒙 一脖苏、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧定踱,春花似錦棍潘、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽恤浪。三九已至,卻和暖如春肴楷,著一層夾襖步出監(jiān)牢的瞬間水由,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評論 1 271
  • 我被黑心中介騙來泰國打工赛蔫, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留砂客,地道東北人。 一個月前我還...
    沈念sama閱讀 48,308評論 3 372
  • 正文 我出身青樓呵恢,卻偏偏與公主長得像鞠值,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子渗钉,可洞房花燭夜當晚...
    茶點故事閱讀 45,037評論 2 355

推薦閱讀更多精彩內容

  • 從三月份找實習到現(xiàn)在彤恶,面了一些公司,掛了不少晌姚,但最終還是拿到小米粤剧、百度、阿里挥唠、京東抵恋、新浪、CVTE宝磨、樂視家的研發(fā)崗...
    時芥藍閱讀 42,253評論 11 349
  • 一.線程安全性 線程安全是建立在對于對象狀態(tài)訪問操作進行管理弧关,特別是對共享的與可變的狀態(tài)的訪問 解釋下上面的話: ...
    黃大大吃不胖閱讀 842評論 0 3
  • layout: posttitle: 《Java并發(fā)編程的藝術》筆記categories: Javaexcerpt...
    xiaogmail閱讀 5,826評論 1 19
  • 成長泛指事物走向成熟的過程窿祥。對于人來說株憾,年齡的增加,身體的成熟都是成長晒衩,心靈的飽滿與成熟更是成長路上重要的一課嗤瞎。如...
    小個子灰狼閱讀 351評論 2 2
  • 對象創(chuàng)建 原型(Prototype) 使用原型實例指定創(chuàng)建對象的種類,并通過復制這個原型創(chuàng)建新的對象听系。 NSArr...
    消失的BUG閱讀 486評論 0 0