當線程類已繼承其他類時,無法繼承 Thread,只能實現 Runnable;且統一實現介面風格,便於線程池提交、解耦任務與執行機制。
new Thread(),未獲取資源start() 後,就緒等待 CPUrun()run() 結束或異常終止public class Account {
private String name;
private int balance; // 余額
public synchronized void deposit(int amount) { // 存款
balance += amount;
}
public synchronized int withdraw(int amount) { // 取款
if (balance >= amount) {
balance -= amount;
return amount;
} else {
int all = balance;
balance = 0;
return all; // 余額不足取走全部
}
}
public synchronized int getBalance() { return balance; }
// getter/setter 略
}
關鍵:所有操作共享資源的方法加 synchronized,保證原子性與可見性。
public class SaveMoney extends Thread {
private Account account;
private int amount;
public SaveMoney(Account account, int amount) {
this.account = account;
this.amount = amount;
}
@Override
public void run() {
int before = account.getBalance();
synchronized (account) { // 雙重保險:方法鎖 + 代碼塊鎖
try { Thread.sleep(5); } catch (InterruptedException e) { e.printStackTrace(); }
account.deposit(amount);
System.out.printf("用戶 %s 存款 %d,存前余額 %d,存後余額 %d%n",
account.getName(), amount, before, account.getBalance());
}
}
}
public class FetchMoney extends Thread {
private Account account;
private int amount;
public FetchMoney(Account account, int amount) {
this.account = account;
this.amount = amount;
}
@Override
public void run() {
int before = account.getBalance();
synchronized (account) {
try { Thread.sleep(5); } catch (InterruptedException e) { e.printStackTrace(); }
int got = account.withdraw(amount);
System.out.printf("用戶 %s 取款 %d,取前余額 %d,實取 %d,取後余額 %d%n",
account.getName(), amount, before, got, account.getBalance());
}
}
}
public class ThreadATMDemo {
public static void main(String[] args) {
Account acc = new Account();
acc.setName("ZhouHaiTao");
acc.setValue(0);
new SaveMoney(acc, 100).start(); // 存 100
new SaveMoney(acc, 200).start(); // 存 200
new FetchMoney(acc, 500).start(); // 取 500(余額不足)
}
}
用戶 ZhouHaiTao 存款 100,存前余額 0,存後余額 100 用戶 ZhouHaiTao 存款 200,存前余額 0,存後余額 300 用戶 ZhouHaiTao 取款 500,取前余額 0,實取 300,取後余額 0
輸出順序不固定(取決於線程調度),但余額計算始終正確,證明 synchronized 正確保護了臨界區。
ReentrantLock + Condition 替代 synchronized,支援公平鎖、可中斷等待、多條件變量BigDecimal 避免浮點誤差