国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

Manual Pembangunan Java Alibaba / 并發(fā)處理

并發(fā)處理

1. 【強(qiáng)制】獲取單例對象需要保證線程安全,其中的方法也要保證線程安全。

說明:資源驅(qū)動類、工具類、單例工廠類都需要注意。

2. 【強(qiáng)制】創(chuàng)建線程或線程池時請指定有意義的線程名稱,方便出錯時回溯。

正例:

public class TimerTaskThread extends Thread {
public TimerTaskThread(){
super.setName("TimerTaskThread"); ...
}

3. 【強(qiáng)制】線程資源必須通過線程池提供,不允許在應(yīng)用中自行顯式創(chuàng)建線程。

說明:使用線程池的好處是減少在創(chuàng)建和銷毀線程上所花的時間以及系統(tǒng)資源的開銷,解決資源不足的問題。如果不使用線程池,有可能造成系統(tǒng)創(chuàng)建大量同類線程而導(dǎo)致消耗完內(nèi)存或者“過度切換”的問題。


4. 【強(qiáng)制】線程池不允許使用 Executors 去創(chuàng)建,而是通過 ThreadPoolExecutor 的方式,這樣的處理方式讓寫的同學(xué)更加明確線程池的運(yùn)行規(guī)則,規(guī)避資源耗盡的風(fēng)險(xiǎn)。

說明: Executors 返回的線程池對象的弊端如下:

1) FixedThreadPool SingleThreadPool :

允許的請求隊(duì)列長度為 Integer.MAX_VALUE ,可能會堆積大量的請求,從而導(dǎo)致 OOM 。

2) CachedThreadPoolScheduledThreadPool :

允許的創(chuàng)建線程數(shù)量為 Integer.MAX_VALUE ,可能會創(chuàng)建大量的線程,從而導(dǎo)致 OOM 。


5. 【強(qiáng)制】 SimpleDateFormat 是線程不安全的類,一般不要定義為 static 變量,如果定義為static ,必須加鎖,或者使用 DateUtils 工具類。

正例:注意線程安全,使用 DateUtils 。亦推薦如下處理:

private static final ThreadLocal<DateFormat> df = new ThreadLocal<DateFormat>() {
@ Override
protected DateFormat initialValue() {
return new SimpleDateFormat("yyyy-MM-dd");
}
};

說明:如果是 JDK 8 的應(yīng)用,可以使用 Instant 代替 Date , LocalDateTime 代替 Calendar ,DateTimeFormatter 代替 Simpledateformatter ,官方給出的解釋: simple beautiful strongimmutable thread - safe 。


6. 【強(qiáng)制】高并發(fā)時,同步調(diào)用應(yīng)該去考量鎖的性能損耗。能用無鎖數(shù)據(jù)結(jié)構(gòu),就不要用鎖 ; 能鎖區(qū)塊,就不要鎖整個方法體 ; 能用對象鎖,就不要用類鎖。


7. 【強(qiáng)制】對多個資源、數(shù)據(jù)庫表、對象同時加鎖時,需要保持一致的加鎖順序,否則可能會造成死鎖。

說明:線程一需要對表 A 、 B 、 C 依次全部加鎖后才可以進(jìn)行更新操作,那么線程二的加鎖順序也必須是 A 、 B 、 C ,否則可能出現(xiàn)死鎖。


8. 【強(qiáng)制】并發(fā)修改同一記錄時,避免更新丟失,要么在應(yīng)用層加鎖,要么在緩存加鎖,要么在數(shù)據(jù)庫層使用樂觀鎖,使用 version 作為更新依據(jù)。

說明:如果每次訪問沖突概率小于 20%,推薦使用樂觀鎖,否則使用悲觀鎖。樂觀鎖的重試次

數(shù)不得小于 3 次。


9. 【強(qiáng)制】多線程并行處理定時任務(wù)時, Timer 運(yùn)行多個 TimeTask 時,只要其中之一沒有捕獲拋出的異常,其它任務(wù)便會自動終止運(yùn)行,使用 ScheduledExecutorService 則沒有這個問題。


10. 【推薦】使用 CountDownLatch 進(jìn)行異步轉(zhuǎn)同步操作,每個線程退出前必須調(diào)用 countDown

方法,線程執(zhí)行代碼注意 catch 異常,確保 countDown 方法可以執(zhí)行,避免主線程無法執(zhí)行

至 countDown 方法,直到超時才返回結(jié)果。

說明:注意,子線程拋出異常堆棧,不能在主線程 try - catch 到。


11. 【推薦】避免 Random 實(shí)例被多線程使用,雖然共享該實(shí)例是線程安全的,但會因競爭同一seed 導(dǎo)致的性能下降。

說明: Random 實(shí)例包括 java . util . Random 的實(shí)例或者  Math . random() 實(shí)例。

正例:在 JDK 7 之后,可以直接使用 API ThreadLocalRandom ,在  JDK 7 之前,可以做到每個

線程一個實(shí)例。


12. 【推薦】通過雙重檢查鎖 (double - checked locking)( 在并發(fā)場景 ) 實(shí)現(xiàn)延遲初始化的優(yōu)化問題隱患 ( 可參考  The " Double - Checked Locking is Broken "  Declaration) ,推薦問題解決方案中較為簡單一種 ( 適用于 JDK 5 及以上版本 ) ,將目標(biāo)屬性聲明為  volatile 型 。

反例:

class Foo {
private Helper helper = null;
public Helper getHelper() {
if (helper == null) synchronized(this) {
if (helper == null)
helper = new Helper();
}
return helper;
}
// other functions and members...
}

13. 【參考】 volatile 解決多線程內(nèi)存不可見問題。對于一寫多讀,是可以解決變量同步問題,但是如果多寫,同樣無法解決線程安全問題。如果是 count ++操作,使用如下類實(shí)現(xiàn):AtomicInteger count =  new AtomicInteger(); count . addAndGet( 1 );  如果是 JDK 8,推薦使用 LongAdder 對象,比 AtomicLong 性能更好 ( 減少樂觀鎖的重試次數(shù) ) 。


14. 【參考】  HashMap 在容量不夠進(jìn)行 resize 時由于高并發(fā)可能出現(xiàn)死鏈,導(dǎo)致 CPU 飆升,在

開發(fā)過程中注意規(guī)避此風(fēng)險(xiǎn)。


15. 【參考】 ThreadLocal 無法解決共享對象的更新問題, ThreadLocal 對象建議使用 static修飾。這個變量是針對一個線程內(nèi)所有操作共有的,所以設(shè)置為靜態(tài)變量,所有此類實(shí)例共享此靜態(tài)變量 ,也就是說在類第一次被使用時裝載,只分配一塊存儲空間,所有此類的對象 ( 只要是這個線程內(nèi)定義的 ) 都可以操控這個變量。