java - 仅使用 volatile 检查并行完成

标签 java concurrency volatile

考虑这些指示两个不同任务完成的共享标志:

volatile boolean completed1 = false;
volatile boolean completed2 = false;

现在考虑两个线程:

没有。 1:

completed1 = true;
if (completed1 && completed2) continueSomeOtherStuff();

没有。 2:

completed2 = true;
if (completed1 && completed2) continueSomeOtherStuff();

continueSomeOtherStuff() 会至少可靠地调用一次吗?

更新:

http://www.cs.umd.edu/~pugh/java/memoryModel/jsr133.pdfhappens-before的定义中找到它:

  • 线程中的每个操作都发生在该线程中的每个后续操作之前。
  • 监视器上的解锁发生在该监视器上的每个后续锁定之前。
  • 对 volatile 字段的写入发生在该 volatile 字段的每次后续读取之前。

最后一句中没有提到线程关系,因此我认为它在所有线程中都有效。

最佳答案

首先代码可以简化如下:

第一:

completed1 = true;
if (completed2) continueSomeOtherStuff();

第二:

completed2 = true;
if (completed1) continueSomeOtherStuff();

不改变行为,因为删除的变量只能由修改它们的线程读取,所以它们始终为真。

由于您已将变量声明为 volatile ,Java 内存模型保证每个线程立即“看到”其他线程的修改。这意味着所有缓存都必须失效,并且不允许 JVM 编译器重新排序或优化这些变量的读取。

因此,在您的情况下,可以保证 continueSomeOtherStuff() 方法至少被调用一次。它也可以被调用两次,在极少数情况下,两个线程都在评估条件之前执行了第一个赋值。

关于java - 仅使用 volatile 检查并行完成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40940318/

相关文章:

java - 如何控制静态方法和实例方法之间的同步访问

java - 无法理解 Java 规范中的 volatile 示例

java - Volatile是线程安全的那么AtomicInteger需要什么

java - 如何使用 jsp 获得最佳性能?

java - 如何获取 IFile 的完全限定名称?

java - 我应该直接访问 int 还是从 getter 获取 double 并进行转换?

java - 我应该使用 ExecutorService 吗?

java - 避免变量持久化

java - Java指南中关于并发的问题

java - 并发、对象可见性