我有一个java类,它有一些(私有静态)同步方法,我想从本机代码调用。使用一些示例代码,我的意思更清楚
public class SomeClass {
private static synchronized void method() {
//do something that needs synchronization
}
}
和相关的本机代码(C ++)
void someFunction(JNIEnv * env) {
jclass someClass = env->findClass("SomeClass");
jmethodID methodId = env->GetStaticMethodID(jclass, "method", "()V");
env->MonitorEnter(jclass); // <--- IS THIS NEEDED/ALLOWED
env->CallStaticVoidMethod(jclass, methodId);
env->MonitorExit(jclass); // <--- IS THIS NEEDED/ALLOWED
}
所以我想知道的是,我是否需要调用MonitorEnter / MonitorExit,或者是否已经通过SomeClass.method()上的synchronized属性强制执行方法同步。 我对重写代码并不感兴趣。我可以想到一些解决方案来解决这个问题,但是我感兴趣的是行为是什么,给定一个从本机代码调用的同步方法。
答案 0 :(得分:6)
Java语言规范的第8.4.3.6 synchronized Methods节说,声明同步方法与在方法中添加同步块具有相同的效果。
答案 1 :(得分:3)
不,不需要明确的MonitorEnter
/ MonitorExit
。根据{{3}},
...最好用Java编程语言表达同步结构。例如,如果静态本机方法需要进入与其定义类关联的监视器,则应该定义静态同步本机方法,而不是在本机代码中执行JNI级监视器同步。
即使您在本规范中没有直接讨论从本机代码调用Java方法(反之亦然)的情况,也没有说明相反的情况,所以我假设它的工作方式类似。
答案 2 :(得分:0)
如果您拥有SomeClass
,则可以执行
public class SomeClass {
private static synchronized void method() {
//do something that needs synchronization
}
private static void synchronizedMethod() {
method();
}
}
然后从C ++调用synchronizedMethod()
。