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 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 love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With