2011-09-28 15 views
9

Tengo una clase java que tiene algunos métodos (privados estáticos) sincronizados a los que también quiero llamar desde código nativo. con un código de ejemplo se hace más claro lo que quiero deciracceda al método sincronizado de java desde el código nativo

public class SomeClass { 
    private static synchronized void method() { 
    //do something that needs synchronization 
    } 
} 

y el código nativa asociada (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 
} 

Así que lo que me pregunto es si tengo que llamar MonitorEnter/MonitorExit, o si la sincronización del método ya se aplica por el atributo sincronizado en SomeClass.method(). No estoy tan interesado en volver a escribir el código. Puedo pensar en algunas soluciones para evitar esto, pero estoy interesado en cuál es el comportamiento, dado un método sincronizado que se llama desde código nativo.

Respuesta

6

La sección 8.4.3.6 synchronized Methods de la Especificación del lenguaje Java dice que declarar el método sincronizado tiene el mismo efecto que agregar un bloque sincronizado dentro del método.

+0

¡Gracias! Dado que se especifica que tienen el mismo efecto, supondré que generan el mismo código de bytes, por lo que MonitorEnter/MonitorExit no son necesarios/redundantes aquí. –

0

Si es el propietario SomeClass que sólo puede hacer

public class SomeClass { 
private static synchronized void method() { 
    //do something that needs synchronization 
    } 

private static void synchronizedMethod() { 
    method(); 
    } 
} 

y simplemente llamar synchronizedMethod() de C++.

+0

Claro, esa es una de las alternativas. Sin embargo, como dije, no estoy tan interesado en reescribir el código. Me gustaría entender qué está pasando. –

3

No, explícita MonitorEnter/MonitorExit no son necesarios. De acuerdo con The JNI guide,

... es preferible expresar las construcciones de sincronización en el lenguaje de programación Java. Si, por ejemplo, un método nativo estático necesita ingresar al monitor asociado con su clase de definición, debe definir un método nativo sincronizado estático en lugar de realizar la sincronización del monitor de nivel JNI en el código nativo.

pesar de que su caso de llamar a un método Java desde el código nativo (y no viceversa) no se discute directamente en la especificación, lo contrario no se dice tampoco, así que podría suponer que funciona similar.

+0

Gracias. Había encontrado esta información antes, pero como esta es la dirección opuesta, no estoy tan seguro. Si el método sincronizado se compila en algo similar a method() {synchronized (this) {method body}} tampoco esperaría problemas. Simplemente no estoy seguro de qué código de bytes se genera para esto, y cuál es exactamente el punto de entrada para la llamada jni. –

+0

@Eric Moors: para estar absolutamente seguro de que es el mismo código de bytes, no hay otra manera que inspeccionar el código de bytes. Pero casi apostaría a que sí. –

Cuestiones relacionadas