1

1)我有一个本地java函数,它传递几个参数,它的实现是一个本地C++构造函数来创建一个对象并返回一个从指针到对象的long。该对象的构造成员实际上是不可变的。然后,C++ 对象可以根据其构造状态进行工作。

2) 获取函数调用结果的 java 代码在某处安全地发布指针的加长版本(没有互斥体)并更改 volatile 变量以希望将本机 C++ 对象中的内存更改发布到其他线程

现在另一个线程读取 2) 的 volatile 变量,然后获取已发布的 long,并调用另一个本机函数,该函数访问 C++ 内存空间中的有效不可变对象以完成一些工作。

问题:由于 Java 内存模型对 volatile 和栅栏的保证,是否保证其他线程可以看到完全构造的本机对象?我敢打赌,在某些平台上答案是肯定的,但我看到不同的芯片使用栅栏以不同的方式工作,并且想知道所有可以使用 java 的平台。

4

3 回答 3

2

JCIP 的合著者在 JSR 邮件列表中回答了并发问题。

他说:“JMM [不] 保证扩展到 Java 堆之外的任何东西——或者更具体地说,它只适用于 Java 字段”,但“实际上,今天使用的障碍/栅栏是粗粒度的,并且会平等地影响所有内存”,因此“在实践中,这个 [问题中描述的易失性发布尝试] 将正常工作(只要您使用正常的进程内存)”。

邮件列表上的另一位受访者说:“我们中的一些人肯定认为它的目标是确保 Java、C 和 C++ 同步按预期协同工作,Java 同步为 C 或 C++ 变量提供正确的可见性保证,反之亦然”但补充说“没有关于[行为]的书面保证”。

于 2012-08-27T23:31:16.023 回答
0

Java 甚至不知道您在 C 代码中创建的本机对象的存在,那么它的内存模型怎么可能提供任何关于它的保证呢?Java 所知道的并可以保证其行为的是 volatile long。

于 2012-08-27T21:49:37.843 回答
0

您从 java 代码传递到本机代码的内容将被复制并传入本机代码的适当数据类型(例如C++,有unsigned intwhileJava没有、null终止的字符串等)。
之后,任何线程问题都与本机代码的实现有关。
本质上它是同一个 API。API 的合约是什么?它是否指定它可以被多个线程安全访问?

于 2012-08-26T13:31:51.887 回答