Java 通過 synchronized 關鍵字提供四種鎖粒度:
synchronized method() — 鎖當前對象實例synchronized (objectReference) { /* block */ } — 鎖指定對象static synchronized method() — 鎖類對象(Class 對象)synchronized (ClassName.class) { /* block */ } — 鎖類對象關鍵點:1 和 2 鎖的是對象實例(一個對象一把鎖);3 和 4 鎖的是類(該類所有實例共享一把鎖)。synchronized method 鎖的是對象而非方法本身——若兩個線程共享同一引用,調用該類任意 synchronized 方法都會互斥。
若需保證兩個方法調用順序不可被打斷,可引入專用鎖對象:
class MyLock {
private final Object lock = new Object();
public void doInOrder() {
synchronized(lock) {
// 先調用 methodA 再調用 methodB,順序不可被打斷
}
}
}
參考 Effective Java Item 52:
String、Integer,天生線程安全。java.util.Timer,內部同步,可直接並發使用。Vector、Hashtable,單方法安全,但複合操作需外部同步。synchronized 輔助實現安全。wait(),防止虛假喚醒。notifyAll() 而非 notify(),避免信號丟失。Java 提供四個管道類實現生產者-消費者模式:
PipedOutputStream pout1 = new PipedOutputStream();
PipedInputStream pin1 = new PipedInputStream(pout1);
PipedOutputStream pout2 = new PipedOutputStream();
PipedInputStream pin2 = new PipedInputStream(pout2);
Producer prod = new Producer(pout1);
Filter filt = new Filter(pin1, pout2);
Consumer cons = new Consumer(pin2);
prod.start(); filt.start(); cons.start();