目錄表

, ,

Effective Java - Synchronize access to shared mutable data

Introduction

這個Item主要在宣導「針對多執行緒會共享的變數,應該要Synchronize access;為了提高效能而不使用它,是非常危險且錯誤的。」要能寫出正確且效能好的程式碼,首先必須要了解原子性、有序性、可見性這三個特性:

再來必須了解的是處理方法,最簡單的是直接使用synchronized去做mutual exclusion:

synchronized(mutex_object) {
    // operations on the mutex_object
}
synchronized可以保證上面提到的三個特性,但最大的缺點就是無法被interrupted;如果可以的話,建議使用Lock相關的API。

另外常被誤用的就是volatile。volatile可以確保可見性與有序性,但它無法保證原子性,如果在多執行緒的存取下,一樣有可能造成不正確的結果。

最後一個要提的就是java.util.concurrent.atomic內的Atomic類。它是透過volatile加CAS(Compare and set)來達到thread-safe與lock-free的特性,因此往往能獲得比較好的效能:
// Lock-free synchronization with java.util.concurrent.atomic
private static final Atomiclong nextSerialNum = new Atomiclong();
public static long generateSerialNumber() {
    return nextSerialNum.getAndIncrement();
}
Effective Java只做了基本的介紹,如果要知道更進階的使用方法,我覺得「Java高併發編程詳解:多線程與架構設計」很不錯。

Note

Effective Java第三版Item 78。

Reference