jni / java:线程安全发布/共享有效不可变的本机对象

时间:2012-08-26 13:24:47

标签: java thread-safety java-native-interface volatile memory-fences

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

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

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

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

3 个答案:

答案 0 :(得分:2)

JCIP的共同作者在JSR邮件列表上回答了关于并发性的问题。

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

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

答案 1 :(得分:0)

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

答案 2 :(得分:0)

Java甚至不知道您在C代码中创建的本机对象是否存在,那么它的内存模型如何可能对它提供任何保证呢?所有Java都知道并且可以保证其行为的是挥发性的。