gpt4 book ai didi

java - 这段代码是否正确使用了 ReentrantReadWriteLock?

转载 作者:太空宇宙 更新时间:2023-11-04 06:19:35 27 4
gpt4 key购买 nike

我熟悉在一个帐户和另一个帐户之间转账时使用同步的并发示例,例如,两个帐户的锁定是根据帐号排序的,这样就不会发生死锁。

我想探索使用 ReentrantReadWriteLock,因为在我看来,这将允许 Account 对象的客户端进行并发读取,前提是没有客户端更新该对象。

我已经编写了代码并对其进行了测试,它似乎可以工作,但看起来有点难看,例如,Account 类公开其锁对象看起来有点奇怪,但似乎必须这样做?还想知道是否有任何我没有发现的潜在错误。

getBalance() 方法是否做了正确的事情来确保内存可见性?

在 getBalance() 中,try 中的“返回”看起来很丑陋,但是必须在锁仍然存在的情况下读取余额字段?

private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();

public void writeLock(){
lock.writeLock().lock();
}
public void readLock(){
lock.readLock().lock();
}
public void writeUnlock(){
lock.writeLock().unlock();
}
public void readUnlock(){
lock.readLock().unlock();
}

public void transferToSafe(Account b, BigDecimal amount){

Account firstAccountToLock=null;
Account secondAccountToLock=null;

// Let the smaller account always get the first lock
if (this.getAccountNo() < b.getAccountNo()){
firstAccountToLock = this;
secondAccountToLock = b;
}
else {
firstAccountToLock = b;
secondAccountToLock = this;
}
try {
firstAccountToLock.writeLock();

try {
secondAccountToLock.writeLock();

this.subtractFromBalance(amount);
b.addToBalance(amount);

}
finally {
secondAccountToLock.writeUnlock();
}
}
finally {
firstAccountToLock.writeUnlock();
}
}

public BigDecimal getBalance(){
try {
this.readLock();
return balance;
}
finally {
this.readUnlock();
}
}

最佳答案

您的锁顺序和死锁预防机制看起来都不错,但有两个建议 subtractFromBalanceaddToBalance确保正确性(并且您的代码可能已经这样做了)

  1. subtractFromBalance内进行验证和addToBalance ,即抛出 IllegalArgumentException或者无论如何 amount大于 subtractFromBalance 的当前余额(我假设不允许出现负余额)。您可能会提前进行此验证,但您还需要在获取锁后进行此验证。

  2. 调用 isHeldByCurrentThread subtractFromBalance 内的写锁和addToBalance如果没有持有锁,则抛出异常。

如果您能够承受数据中的一些临时不一致,那么您可以完全消除读锁定:使用 AtomicReference<BigDecimal>余额( getBalance() 简单地变成 return balance.get() )。不一致之处在于,如果您从 AccountA 中减去钱,并将其添加到 AccountB然后同时调用getBalance可能会返回 AccountA 的新余额旧余额为 AccountB ,但是这在您的系统中可能是安全的,因为它只会低估可用资金,并且帐户最终会保持一致。

关于java - 这段代码是否正确使用了 ReentrantReadWriteLock?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27590181/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com