使用本地變量
盡量使用本地變量,而不是創建一個類或實例的變量。
使用不可變類
String、Integer等。不可變類可以降低代碼中需要的同步數量。
最小化鎖的作用域范圍:S=1/(1-a+a/n)
a:並行計算部分所占比例
n:並行處理結點個數
S:加速比
當1-a等於0時,沒有串行只有並行,最大加速比 S=n
當a=0時,只有串行沒有並行,最小加速比 S = 1
當n→∞時,極限加速比 s→ 1/(1-a)
例如,若串行代碼占整個代碼的25%,則並行處理的總體性能不可能超過4。
該公式稱為:"阿姆達爾定律"或"安達爾定理"。
使用線程池的Executor,而不是直接new Thread 執行
創建一個線程的代價是昂貴的,如果要創建一個可伸縮的Java應用,那么你需要使用線程池。
寧可使用同步也不要使用線程的wait和notify
從Java1.5以后,增加了許多同步工具,如:CountDownLatch、CyclicBarrier、Semaphore等,應該優先使用這些同步工具。
使用BlockingQueue實現生產-消費模式
阻塞隊列不僅可以處理單個生產、單個消費,也可以處理多個生產和消費。
使用並發集合而不是加了鎖的同步集合
Java提供了下面幾種並發集合框架:
ConcurrentHashMap、CopyOnWriteArrayList、CopyOnWriteArraySet、ConcurrentLinkedQueue 、ConcurrentLinkedDeque等(相關介紹請見Java 並發編程(九)並發集合框架)
使用Semaphore創建有界的訪問
為了建立穩定可靠的系統,對於數據庫、文件系統和socket等資源必須要做有機的訪問,Semaphore可以限制這些資源開銷的選擇,Semaphore可以以最低的代價阻塞線程等待,可以通過Semaphore來控制同時訪問指定資源的線程數。
寧可使用同步代碼塊,也不實用同步的方法
主要針對synchronized關鍵字。使用synchronized關鍵字同步代碼塊只會鎖定一個對象,而不會將整個方法鎖定。如果更改共同的變量或類的字段,首先應該選擇的是原子型變量,然后使用volatile。如果需要互斥鎖,可以考慮使用ReentrantLock。
避免使用靜態變量
靜態變量在並發執行環境下會制造很多問題,如果必須使用靜態變量,那么優先是它成為final變量,如果用來保存集合collection,那么可以考慮使用只讀集合,否則一定要做特別多的同步處理和並發處理操作。