1) 我有一个 native java函数,它传递几个参数,它的实现是一个 native C++构造函数,用于创建一个对象并返回一个从指针到对象的转换的long。该对象的构造成员实际上是不可变的。然后,C++ 对象可以根据其构造状态进行工作。
2) 获取函数调用结果的 java 代码安全地将指针的长化版本发布到某处(没有互斥体),并更改 volatile 变量,以希望将 native C++ 对象中的内存更改发布到其他线程
现在另一个线程读取 2) 的 volatile 变量,然后获取已发布的 long,并调用另一个 native 函数来访问 C++ 内存空间中的有效不可变对象(immutable对象)来执行一些工作。
问题:由于 Java 内存模型对 volatile 和栅栏的保证,其他线程是否能保证看到完全构造的 native 对象?我敢打赌,在某些平台上答案是肯定的,但我发现不同的芯片使用栅栏以不同的方式工作,并且想知道 java 可用的所有平台。
最佳答案
JCIP 的合著者在 JSR 邮件列表上回答了有关并发的问题。
他说:“JMM [不]保证扩展到 Java 堆之外的任何内容 - 或者更具体地说,它仅适用于 Java 字段”,但“实际上,今天使用的屏障/栅栏是粗粒度的,会影响所有内存均等”,因此“实际上,[问题中描述的 volatile 发布尝试]将正常工作(只要您使用正常的进程内存)”。
邮件列表中的另一位受访者表示:“我们中的一些人确实认为确保 Java、C 和 C++ 同步按预期协同工作是一个目标,Java 同步为 C 或 C++ 变量提供正确的可见性保证,反之亦然”,但补充说“没有对该[行为]的书面保证”。
关于java - jni/java : thread safe publishing/sharing of effectively immutable native object,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12130487/