并發(fā)(十一)

多線程并發(fā)最佳實踐

  • 使用本地變量

應盡量使用本地變量,而不是創(chuàng)建一個類或?qū)嵗淖兞?/p>

  • 使用不可變類

不可變類比如String、Integer等一旦創(chuàng)建,不再改變,不可變類可以降低代碼中需要的同步數(shù)量

  • 最小化鎖的作用域范圍

任何在鎖中的代碼將不能被并發(fā)執(zhí)行,如果你有5%代碼在鎖中,那么根據(jù)Amdahl's law,你的應用性能就不可能提高超過20倍,因為鎖中這些代碼只能順序執(zhí)行,降低鎖的涵括范圍,上鎖和解鎖之間的代碼越少越好

  • 使用線程池的Excutor,而不是直接new Thread執(zhí)行

創(chuàng)建一個線程的代價是昂貴的,如果你要得到一個可伸縮的Java應用,你需要使用線程池,使用線程池管理線程。JDK提供了各種ThreadPool線程池和Executor

  • 寧可使用同步也不要使用線程的wait和notify

從Java 1.5以后增加了需要同步工具如CycicBariier, CountDownLatch 和 Sempahore,你應當優(yōu)先使用這些同步工具,而不是去思考如何使用線程的wait和notify,通過BlockingQueue實現(xiàn)生產(chǎn)-消費的設(shè)計比使用線程的wait和notify要好得多,也可以使用CountDownLatch實現(xiàn)多個線程的等待

  • 使用BlockingQueue實現(xiàn)生產(chǎn)-消費模式

大部分并發(fā)問題都可以使用producer-consumer生產(chǎn)-消費設(shè)計實現(xiàn),而BlockingQueue是最好的實現(xiàn)方式,堵塞的隊列不只是可以處理單個生產(chǎn)單個消費,也可以處理多個生產(chǎn)和消費

  • 使用并發(fā)集合Collection而不是加了同步鎖的集合

Java提供了 ConcurrentHashMap CopyOnWriteArrayList 和 CopyOnWriteArraySet以及BlockingQueue Deque and BlockingDeque五大并發(fā)集合,寧可使用這些集合,也不用使用Collections.synchronizedList之類加了同步鎖的集合, CopyOnWriteArrayList 適合主要讀很少寫的場合,ConcurrentHashMap更是經(jīng)常使用的并發(fā)集合

  • 使用Semaphore創(chuàng)建有界

為了建立可靠的穩(wěn)定的系統(tǒng),對于數(shù)據(jù)庫 文件系統(tǒng)和socket等資源必須有界bound,Semaphore是一個可以限制這些資源開銷的選擇,如果某個資源不可以,使用Semaphore可以最低代價堵塞線程等待

  • 寧可使用同步代碼塊,也不使用加同步的方法

使用synchronized 同步代碼塊只會鎖定一個對象,而不會將當前整個方法鎖定;如果更改共同的變量或類的字段,首先選擇原子性變量,然后使用volatile。如果你需要互斥鎖,可以考慮使用ReentrantLock

  • 避免使用靜態(tài)變量

靜態(tài)變量在并發(fā)執(zhí)行環(huán)境會制造很多問題,如果你必須使用靜態(tài)變量,讓它稱為final 常量,如果用來保存集合Collection,那么考慮使用只讀集合

  • 寧可使用鎖,而不是synchronized 同步關(guān)鍵字

Lock鎖接口是非常強大,粒度比較細,對于讀寫操作有不同的鎖,這樣能夠容易擴展伸縮,而synchronized不會自動釋放鎖,如果你使用lock()上鎖,你可以使用unlock解鎖

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內(nèi)容