【问题标题】:Is it right to define native method as public native synchronized int doSum(int a, int b)?将本机方法定义为公共本机同步int doSum(int a,int b)是否正确?
【发布时间】:2013-03-01 07:38:50
【问题描述】:

我对多线程环境下的 JNI 实现感到困惑。我有一个如下的 java 类,代表本机接口:

public class Test {
    public native int doSum(int a, int b);
}

并且对应的native方法是在c中实现的。

现在,我的问题是,我有多个线程,比如 5 个。所有线程都在使用上述 Test 类的一个全局实例。那么,用 C 编写的本地方法代码是否可能是线程安全的?或者我是否需要像问题中提到的那样使其线程安全?

如果我为每个线程创建单独的 Test 类实例,然后调用本机函数呢?这会表现出线程安全吗?

谢谢。

【问题讨论】:

  • 不知道方法的实现我们是无法判断的。如果实现是线程安全的,则不需要同步。如果它不是线程安全的,则同步可以使其成为线程安全的。这完全取决于方法的代码。

标签: java c++ multithreading android-ndk java-native-interface


【解决方案1】:

将native方法定义为public native synchronized int doSum(int a, int b)对吗?

如果你希望它是一个接受两个整数参数并返回一个整数结果的同步方法是正确的。只有你自己知道。

那么,用 C 编写的本地方法代码是否可能是线程安全的?

如果以这种方式实现是可能的。不看代码就说不出来。

或者我是否需要像问题中提到的那样使其线程安全?

如果它的实现还不是线程安全的,并且您的使用模式要求它是线程安全的,则您需要使其成为线程安全的。这不是一个真正的问题。

【讨论】:

  • 我真正的要求是将对象地址(指针)作为整数参数传递给本机函数,如 int doSum(Math* objPtr, jint a, jint b)。在 doSum(...) 的主体中,我将执行 objPtr->Sum(a, b)。你对这种结构有什么建议?如果不定义同步,它会是线程安全的吗?
  • 你一直在问只有你自己知道答案的问题。一个方法是否是线程安全的取决于它里面的内容。
【解决方案2】:

我对用 C 实现的 Java 方法一无所知,但在 C 和 Java 中,如果没有显式同步,就无法保证线程安全。两个线程可以同时执行同一个方法。

“线程安全”意味着一个方法在所有情况下都可以容忍这种情况。想象一下,线程 A 执行了一半的方法,然后暂停,而线程 B 执行了其中的一部分,然后又恢复了......这可能会导致非常难以诊断的错误,所以最好小心。

一般来说,如果该方法正在读取或修改对象状态的任何部分,那么它应该被同步或保持在单个线程的本地。

有很多关于这个主题的好读物。如果您有兴趣,我建议您阅读一本关于并发编程的介绍性书籍。 :)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-03-20
    • 2014-10-19
    • 1970-01-01
    • 2012-08-01
    • 2016-05-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多