java - 使用 Java 锁时出现竞争条件的可能性
问题描述
我编写了一个 Java 类,有人查看了代码并坚持认为方法中可能存在竞争条件calculate
。这是类代码的简化版本:
public class MyClass {
private List<Integer> list;
private final ReadWriteLock lock;
public MyClass() {
list = new ArrayList<>();
lock = new ReentrantReadWriteLock();
}
public void add(Integer integer) {
lock.writeLock().lock();
try {
list.add(integer);
} finally {
lock.writeLock().unlock();
}
}
public void deleteAll() {
lock.writeLock().lock();
try {
list.clear();
} finally {
lock.writeLock().unlock();
}
}
public Integer calculate() {
List<Integer> newList = new ArrayList<>();
Integer result = 0;
lock.readLock().lock();
try {
list.forEach(integer -> {
// calculation logic that reads values from 'list' and adds only a subset of elements from 'list' in 'newList'
});
} finally {
lock.readLock().unlock();
}
setList(newList);
return result;
}
private void setList(List<Integer> newList) {
lock.writeLock().lock();
try {
list = newList;
} finally {
lock.writeLock().unlock();
}
}
}
现在我的问题是:
在这种方法中真的会发生竞争条件吗?如果是这样,我该如何解决它(使用锁或使用任何其他方法来使类线程安全)?
任何意见,将不胜感激。
解决方案
newList
创建和调用之间存在时间间隔setList(newList)
。setList(newList)
我们可以假设这个时间间隔是任意长的,并且当它持续时一切都可能发生,例如另一个线程添加了一个必须保留的对象,但是当调用删除list
该新对象时它将丢失。
实际上,该方法calculate
正在修改并且应该在写锁下完成所有工作。
推荐阅读
- python - 如何设置计算移动平均线的开始时间和结束时间?
- arrays - 如何访问 ada 中 JSON 数组的特定位置?
- javascript - 通过聚合名称或部件名称导入聚合
- java - 回调中可能存在内存泄漏
- javascript - 如何使 node.js 应用程序以编程方式永久运行
- amazon-web-services - AWS ec2 ubuntu+nginx+uwgi+flask 深度学习 api: 504 Gateway Time-out
- arduino - Arduino旋转编码器定时器
- powershell - DevOps Powershell 步骤成功调用 bat 文件但返回 1
- c# - 生成 1 到 10 之间的唯一随机数?
- python - 获取每个合约的唯一 custId 数量