I have a java class that has some (private static) synchronized methods which I want to call from native code as well. with some example code it becomes more clear what I开发者_Python百科 mean
public class SomeClass {
private static synchronized void method() {
//do something that needs synchronization
}
}
and the associated native code (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
}
So what I am wondering is if I need to call MonitorEnter/MonitorExit, or if the method synchronization is enforced already by the synchronized attribute on SomeClass.method(). I am not so much interested in rewriting the code. I can think of a few solutions to work around this, but I am interested in what the behaviour is, given a synchronized method that is called from native code.
Section 8.4.3.6 synchronized Methods of the Java Language Specification says that declaring the method synchronized has the same effect as adding a synchronized block within the method.
No, explicit MonitorEnter
/ MonitorExit
are not needed. According to The JNI guide,
...it is preferable to express synchronization constructs in the Java programming language. If, for example, a static native method needs to enter the monitor associated with its defining class, you should define a static synchronized native method as opposed to performing JNI-level monitor synchronization in native code.
Even though your case of calling a Java method from the native code (and not vice versa) isn't directly discussed in the spec, the opposite is not stated either, so I would assume that it works similarly.
If you own SomeClass
you can just do
public class SomeClass {
private static synchronized void method() {
//do something that needs synchronization
}
private static void synchronizedMethod() {
method();
}
}
and just call synchronizedMethod()
from C++.
精彩评论