gpt4 book ai didi

java - 防止 Java 中的 JIT 重新排序

转载 作者:行者123 更新时间:2023-11-30 07:13:14 24 4
gpt4 key购买 nike

我有一个看起来像是被 JIT 重新排序的方法。

public boolean finishRequest(boolean success) {
if (success) {
error = false;
wayPoints.put(FINISH_SUCCESS_WP, System.currentTimeMillis());
} else {
wayPoints.put(FINISH_ERROR_WP, System.currentTimeMillis());
error = true;
}
someThread.addToQueue(this);//...submit for further processing on separate thread
return true;
}

wayPoints 容器是“this”的一个字段,它被 someThread 访问。当它通过 getWayPoints() 遍历此 wayPoints 时,我最终在 someThread 的某行代码中得到了一个 ConcurrentModificationException。

为了解决这个问题,我创建了一个新的不可变类,它将传递给 someThread 而不是“this”。

public boolean finishRequest(boolean success) {
if (success) {
error = false;
wayPoints.put(FINISH_SUCCESS_WP, System.currentTimeMillis());
} else {
wayPoints.put(FINISH_ERROR_WP, System.currentTimeMillis());
error = true;
}
PLog plog = new PLog(wayPoints.toArray(new WayPoint[wayPoints.size()]));
someThread.addToQueue(plog);//...submit for further processing on separate thread
return true;
}

在第一段代码中,JIT 可以重新排序“someThread.addToQueue()”和“wayPoints.put()”,因为编译器可以从中判断出 wayPoints 没有被进一步读取到当前线程中。但是在固定代码中,由于我正在使用 wayPoints 来构造我的新 PLog 实例,我现在是否有效地阻止了 JIT 重新排序?

引用.... http://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.4.5

从 JLS 第 17.4.5 节的阅读来看,我假设我已经创建了一个具有法律约束力的 happens-before 这将防止重新排序,因为我现在正在写入后从 wayPoints 读取....“如果 x 和y 是同一线程的操作,并且 x 按程序顺序出现在 y 之前,然后是 hb(x, y)。”

谢谢!

最佳答案

您完全正确,您已经创建了一个 happens-before 关系。一般来说

a = X ; ( X 是一些不涉及 a & b 的常量或表达式)b = Y ; ( Y 是一些不涉及 a 和 b 的常量或表达式)

以上两个可以通过JIT重新排序

但是 a = X ;b = a * Y ;

不会重新排序。这几乎就是您在更正中所做的。

解决问题的其他方法是将 wayPoints 声明为易变的。如果您将 wayPoints 声明为 volatile,则写入 volatile (wayPoints) 不会与原始程序顺序中的其他内存操作 (someThread.addToQueue()) 一起重新排序。

关于java - 防止 Java 中的 JIT 重新排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19649588/

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