java - Java 易失性循环
问题描述
我正在研究某人的代码,并遇到了与此类似的情况:
for (int i = 0; i < someVolatileMember; i++) {
// Removed for SO
}
wheresomeVolatileMember
是这样定义的:
private volatile int someVolatileMember;
如果某个线程 A 正在运行 for 循环,而另一个线程 B 写入,someVolatileMember
那么我假设在线程 A 运行循环时要执行的迭代次数会改变,这不是很好。我认为这会解决它:
final int someLocalVar = someVolatileMember;
for (int i = 0; i < someLocalVar; i++) {
// Removed for SO
}
我的问题是:
- 只是为了确认如果线程 B 修改,则可以在 for 循环处于活动状态时更改线程 A 的迭代次数
someVolatileMember
- 本地非易失性副本足以确保当线程 A 运行循环时,线程 B 不能更改迭代次数
解决方案
你的理解是正确的:
根据Java Language Specification,
volatile
字段的语义确保在不同线程之间完成更新后看到的值之间的一致性:Java 编程语言提供了第二种机制,
volatile
即字段,在某些情况下它比锁定更方便。可以声明一个字段
volatile
,在这种情况下,Java 内存模型确保所有线程都看到变量的一致值(第 17.4 节)。请注意,即使没有
volatile
修饰符,循环计数也可能会根据许多因素而变化。一旦
final
分配了变量,它的值就永远不会改变,因此循环计数不会改变。
推荐阅读
- sas - 此范围重复,或值重叠:C811-C811
- vba - 创建宏以仅将某些数据从一个工作表传输到另一个满足条件的工作表
- node.js - NodeJS - express server、pm2 cluser 和 nginx 平衡 - 多线程
- jquery - JQuery / Ajax - 使用 preventDefault() 后表单未提交
- python - Python Pandas Dataframe 动态添加列
- python - python3 HTTP请求需要很长时间
- java - Android l 房间持久化 l 当前周条目
- android-studio - 编译错误-引起:java.lang.ClassNotFoundException:在android studio中找不到类“com.google.android.gms.common.internal.zzbo”
- c# - 对象变量只显示最后一个值
- yaml - 将多个变量作为规范文件的参数传递到 rpmbuild