我似乎找不到任何我想问的例子:
假设我在类里面有帐户
public void transferMoney(Account fromAccount, Account toAccount, DollarAmount amountToTransfer) {
if (fromAccount.hasSufficientBalance(amountToTransfer) {
fromAccount.debit(amountToTransfer);
toAccount.credit(amountToTransfer);
}
}
这在重写的运行方法中使用时可能会导致竞争条件,我在 Main 中有这段代码:
Account acc1 = new Account(..);
Account acc2 = new Account(..);
Thread t1 = new Thread(new Transfer(..from acc1 to acc2..));
Thread t2 = new Thread(new Transfer(..from acc2 to acc1..));
synchronized (acc1) {
t1.start();
}
synchronized (acc2) {
t2.start()
}
同步帐户 acc1 和 acc2 的这两个实例不会阻止竞争条件,但我不知道为什么或同步在这种情况下究竟做了什么! 我找不到任何关于这种同步的例子。
最佳答案
synchronized
仅在线程试图进入 synchronized
block 而另一个线程当前 处于 synchronized< 时才有效
引用同一对象的 block 。在这里,只有您的主线程在 acc1
和 acc2
上同步,因此实际上不会发生任何同步。
针对您的情况,更好的设计是将 hasSufficientBalance
和 debit
聚合到一个同步的方法中(相当于将整个方法主体包含在一个 synchronized(this)
block )。此 synchronized
用于保护类的内部状态。因此,您还需要将 credit
方法标记为 synchronized
。
public synchronized boolean debitIfHasSufficientBalance(DollarAmount amount) {
if (hasSufficientBalance(amount)) {
debit(amount);
return true;
}
return false;
}
您的 transferMoney
可以重写如下,无需任何显式同步:
public void transferMoney(Account fromAccount, Account toAccount, DollarAmount amountToTransfer) {
if (fromAccount.debitIfHasSufficientBalance(amountToTransfer)) {
toAccount.credit(amountToTransfer);
}
}
关于Java 同步类实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26149736/