來源:北大青鳥飛迅校區(qū)|發(fā)布時(shí)間:2013-04-22 11:10:12
Java編程保證線程安全的三種方法
1,保證線程安全的三種方法:a,不要跨線程訪問共享變量b,使共享變量是final類型的c,將共享變量的操作加上同步。
2,一開始就將類設(shè)計(jì)成線程安全的,比在后期重新修復(fù)它,更容易。
3,編寫多線程程序,首先保證它是正確的,其次再考慮性能。
4,無狀態(tài)或只讀對(duì)象永遠(yuǎn)是線程安全的。
5,不要將一個(gè)共享變量裸露在多線程環(huán)境下(無同步或不可變性保護(hù))
6,多線程環(huán)境下的延遲加載需要同步的保護(hù),因?yàn)檠舆t加載會(huì)造成對(duì)象重復(fù)實(shí)例化
7,對(duì)于volatile聲明的數(shù)值類型變量進(jìn)行運(yùn)算,往往是不安全的(volatile只能保證可見性,不能保證原子性)。詳見volatile原理與技巧中,臟數(shù)據(jù)問題討論。
8,當(dāng)一個(gè)線程請(qǐng)求獲得它自己占有的鎖時(shí)(同一把鎖的嵌套使用),我們稱該鎖為可重入鎖。在jdk1.5并發(fā)包中,提供了可重入鎖的java實(shí)現(xiàn)-ReentrantLock。
9,每個(gè)共享變量,都應(yīng)該由一個(gè)唯一確定的鎖保護(hù)。創(chuàng)建與變量相同數(shù)目的ReentrantLock,使他們負(fù)責(zé)每個(gè)變量的線程安全。
10,雖然縮小同步塊的范圍,可以提升系統(tǒng)性能。但在保證原子性的情況下,不可將原子操作分解成多個(gè)synchronized塊。
11,在沒有同步的情況下,編譯器與處理器運(yùn)行時(shí)的指令執(zhí)行順序可能完全出乎意料。原因是,編譯器或處理器為了優(yōu)化自身執(zhí)行效率,而對(duì)指令進(jìn)行了的重排序(reordering)。
12,當(dāng)一個(gè)線程在沒有同步的情況下讀取變量,它可能會(huì)得到一個(gè)過期值,但是至少它可以看到那個(gè)線程在當(dāng)時(shí)設(shè)定的一個(gè)真實(shí)數(shù)值。而不是憑空而來的值。這種安全保證,稱之為最低限的安全性(out-of-thin-air safety)
在開發(fā)并發(fā)應(yīng)用程序時(shí),有時(shí)為了大幅度提高系統(tǒng)的吞吐量與性能,會(huì)采用這種無保障的做法。但是針對(duì),數(shù)值的運(yùn)算,仍舊是被否決的。
13,volatile變量,只能保證可見性,無法保證原子性。
14,某些耗時(shí)較長的網(wǎng)絡(luò)操作或IO,確保執(zhí)行時(shí),不要占有鎖。
15,發(fā)布(publish)對(duì)象,指的是使它能夠被當(dāng)前范圍之外的代碼所使用。(引用傳遞)對(duì)象逸出(escape),指的是一個(gè)對(duì)象在尚未準(zhǔn)備好時(shí)將它發(fā)布。
原則:為防止逸出,對(duì)象必須要被完全構(gòu)造完后,才可以被發(fā)布(最好的解決方式是采用同步)
this關(guān)鍵字引用對(duì)象逸出
例子:在構(gòu)造函數(shù)中,開啟線程,并將自身對(duì)象this傳入線程,造成引用傳遞。而此時(shí),構(gòu)造函數(shù)尚未執(zhí)行完,就會(huì)發(fā)生對(duì)象逸出了。
16,必要時(shí),使用ThreadLocal變量確保線程封閉性(封閉線程往往是比較安全的,但一定程度上會(huì)造成性能損耗)封閉對(duì)象的例子在實(shí)際使用過程中,比較常見,例如hibernate openSessionInView機(jī)制,jdbc的connection機(jī)制。
全程面授,不高薪都難
申請(qǐng)成功后,我們將在24小時(shí)內(nèi)與您聯(lián)系
招生熱線: 4008-0731-86 / 0731-82186801
學(xué)校地址: 長沙市天心區(qū)團(tuán)結(jié)路6號(hào)
Copyright © 2006 | 湖南大計(jì)信息科技有限公司 版權(quán)所有
湘ICP備14017520號(hào)-3