本例演示使用 synchronized 關鍵字實現線程同步:兩個線程並發操作共享賬戶對象(一個存款、一個取款),通過同步方法保證數據一致性。
public class SyThreadDemo {
public static void main(String[] args) {
trade ft = new trade();
addThread tt1 = new addThread(ft, "add");
decThread tt2 = new decThread(ft, "dec");
tt1.start(); tt2.start();
}
}
class trade {
private String transName;
private double amount;
// 同步方法:同一時間只允許一個線程執行
synchronized void update(String transName, double amount) {
this.transName = transName;
this.amount = amount;
System.out.println(this.transName + " " + this.amount);
}
}
class addThread extends Thread {
private trade ft;
addThread(trade ft, String name) { super(name); this.ft = ft; }
public void run() {
for (int i = 0; i < 10; i++) ft.update("add", 2000.0);
}
}
class decThread extends Thread {
private trade fd;
decThread(trade fd, String name) { super(name); this.fd = fd; }
public void run() {
for (int i = 0; i < 10; i++) fd.update("dec", -2000.0);
}
}
synchronized 實例方法鎖住 this 對象,同一對象的所有同步方法互斥// 1. 同步實例方法(鎖 this)
synchronized void update(...) { ... }
// 2. 同步代碼塊(可指定鎖對象,粒度更細)
void update(...) {
synchronized(this) { ... } // 或 synchronized(sharedLock) { ... }
}
// 3. 同步靜態方法(鎖 Class 對象)
static synchronized void staticMethod() { ... }
輸出將嚴格交替顯示 "add 2000.0" 和 "dec -2000.0",無數據競爭。若去掉 synchronized,可能出現:
| 工具 | 適用場景 | 優勢 |
|---|---|---|
ReentrantLock | 需可中斷、超時、公平鎖、多條件變量 | 功能豐富、性能優於 synchronized(高爭用時) |
AtomicLong/Double | 單變量原子操作 | 無鎖 CAS,極高性能 |
LongAdder | 高併發計數器 | 分段累加,吞吐量遠超 AtomicLong |
StampedLock | 讀多寫少場景 | 樂觀讀鎖,無阻塞讀取 |
java.util.concurrent 高級組件替代底層同步