gpt4 book ai didi

java尝试终于解锁习语

转载 作者:行者123 更新时间:2023-12-02 09:16:07 24 4
gpt4 key购买 nike

Javadoc 和一些答案( Threads - Why a Lock has to be followed by try and finally )指出:

在大多数情况下,应该使用以下习惯用法:

 Lock l = ...;
l.lock();
try {
// access the resource protected by this lock
} finally {
l.unlock();
}

我在标准 Java 库中看到过这种习惯用法的示例。这是我使用它的例子。字段 acc1 和 acc2 代表银行帐户的一个众所周知的示例。主要约束是 acc 值的总和 - 它应该为 0。

public class Main {
int acc1;
int acc2;

ReadWriteLock lock = new ReentrantReadWriteLock();

public int readSum() {
lock.readLock().lock();
try {
return acc1 + acc2;
} finally {
lock.readLock().unlock();
}
}

public void transfer() {
lock.writeLock().lock();
try {
acc1--; // constraint is corrupted
// exception throwed here
acc2++; // constraint is regained
} finally {
lock.writeLock().unlock();
}
}
}

我理解在读取情况下使用惯用语:如果在读取方法中抛出异常,其他线程仍然可以读取/写入一致的资源。但如果 write 方法抛出异常,read 方法可以读取不一致的资源。

为什么读取不一致的值比无限锁等待更可取?为什么 Java 库作者更喜欢这种行为?

最佳答案

您在这里混淆了不同的概念。有:

  1. 锁定,并防止死锁,然后
  2. 另一个维度,我们称之为“数据完整性”。

要点:这两者基本上是正交的。事实上,您正在解决其中一个问题并不能神奇地为您解决另一个问题!

即使当您查看自己的示例时,您也会发现您在那里添加了 try/finally 。但那里没有陷阱!不惜一切代价含义:如果抛出某个异常,该异常仍然会抛出,并且某些捕获器将不得不处理它。

换句话说:如果您的“锁定”代码可能遇到异常,那么您有责任以最有意义的方式处理该异常。

而且,从“系统”角度来看:当您获得无限期锁定时,迟早会降低整个系统的性能。如果您遇到过一次该异常,那么您会更频繁地遇到它。因此,很可能您很快就会用完线程/锁;你的整个申请都会受到影响。这正是可能导致分布式基础设施瘫痪的问题——一个组件停止处理传入的请求。

长话短说:无限的锁等待是您想要防止的事情,因为它会严重影响应用程序的运行能力!

最后:当然,这是关于不同需求的平衡。但是,例如:假设您的在线商店丢失了您刚刚从购物车中删除商品的信息。是的,这对客户来说很烦人。但比较一下:整个在线购物应用程序停止处理请求;因为锁定问题。哪个问题会对您的业务造成更大的损害?

关于java尝试终于解锁习语,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38684302/

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