1. 悲觀互斥
互斥實際是悲觀鎖的思想
例如,有下面取款的需求
interface Account {
// 獲取餘額
Integer getBalance();
// 取款
void withdraw(Integer amount);
/**
* 方法內會啓動 1000 個線程,每個線程做 -10 元 的操作
* 如果初始餘額爲 10000 那麼正確的結果應當是 0
*/
static void demo(Account account) {
List<Thread> ts = new ArrayList<>();
for (int i = 0; i < 1000; i++) {
ts.add(new Thread(() -> {
account.withdraw(10);
}));
}
long start = System.nanoTime();
ts.forEach(Thread::start);
ts.forEach(t -> {
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
long end = System.nanoTime();
System.out.println(account.getBalance()
+ " cost: " + (end-start)/1000_000 + " ms");
}
}
用互斥來保護
class AccountSync implements Account {
private Integer balance;
public AccountUnsafe(Integer balance) {
this.balance = balance;
}
@Override
public Integer getBalance() {
synchronized (this) {
return this.balance;
}
}
@Override
public void withdraw(Integer amount) {
synchronized (this) {
this.balance -= amount;
}
}
}
2. 樂觀重試
另外一種是樂觀鎖思想,它其實不是互斥
class AccountCas implements Account {
private AtomicInteger balance;
public AccountCas(int balance) {
this.balance = new AtomicInteger(balance);
}
@Override
public Integer getBalance() {
return balance.get();
}
@Override
public void withdraw(Integer amount) {
while(true) {
// 獲取餘額的最新值
int prev = balance.get();
// 要修改的餘額
int next = prev - amount;
// 真正修改
if(balance.compareAndSet(prev, next)) {
break;
}
}
}
}