相关疑难解决方法(0)

指令重新排序和发生在java之前的关系

在Java Concurrency In Practice一书中,我们被告知可以通过编译器,JVM在运行时甚至由处理器重新排序程序的指令.因此,我们应该假设执行的程序不会以与我们在源代码中指定的顺序完全相同的顺序执行其指令.

但是,讨论Java内存模型的最后一章提供了一个先前发生的规则列表,指出了JVM保留了哪些指令排序.这些规则中的第一条是:

  • "程序顺序规则.线程中的每个操作都发生在程序顺序后面的该线程中的每个操作之前."

我相信"程序顺序"是指源代码.

我的问题:假设这个规则,我想知道什么指令可能实际重新排序.

"行动"定义如下:

Java内存模型是根据操作指定的,包括对变量的读取和写入,监视器的锁定和解锁,以及启动和连接线程.JMM定义了在程序中的所有操作之前调用的部分排序.为了保证执行动作B的线程可以看到动作A的结果(A和B是否出现在不同的线程中),必须在A和B之间的关系之前发生.在没有发生之前在两个之间进行排序操作,JVM可以随意重新排序.

其他提到的订单规则是:

  • 监控锁定规则.监视器锁定上的解锁发生在同一监视器锁定的每个后续锁定之前.
  • 易变变量规则.对每个后续读取同一字段之前发生对易失性字段的写入.
  • 线程启动规则.在线程上调用Thread.start会在启动线程中的每个操作之前发生.
  • 线程终止规则.线程中的任何操作都发生在任何其他线程检测到该线程已终止之前,可以通过成功从Thread.join返回,也可以通过Thread.isAlive返回false.
  • 中断规则.另一个线程上的线程调用中断发生在被中断的线程检测到中断之前(通过抛出InterruptedException,或者调用isInterrupted或中断).
  • 终结者规则.对象的构造函数的结束发生在该对象的终结器的开始之前.
  • 及物.如果A发生在B之前,B发生在C之前,那么A发生在C之前.

java concurrency multithreading java-memory-model

51
推荐指数
1
解决办法
1万
查看次数

关于可见性及时性的易失性的详细语义

考虑一下volatile int sharedVar.我们知道JLS为我们提供了以下保证:

  1. 写入线程的每个动作在w其写入值之前isharedVar程序顺序happens-before写入动作;
  2. 的值写入i通过w happens-before的成功读取isharedVar由读取线程r;
  3. 成功读取isharedVar由读线程r happens-before的所有后续行动r的程序顺序.

然而,仍有给出没有挂钟时间的保证,当读线程将观察值i.一个完全不会让读取线程看到该值的实现仍然符合此契约.

我已经考虑了一段时间,我看不到任何漏洞,但我认为必须有.请指出我的推理漏洞.

java volatile java-memory-model

21
推荐指数
1
解决办法
1086
查看次数