Saltar al contenido

¿Cómo sincroniza correctamente los subprocesos en el lado nativo de un entorno JNI?

Nuestros desarrolladores estrellas agotaron sus reservas de café, en su búsqueda diariamente por la respuesta, hasta que Raquel halló la respuesta en Gogs y hoy la compartimos con nosotros.

Si ambos subprocesos están conectados a la JVM, entonces puede acceder a la sincronización de la JNI a través de JNIEnv‘s MonitorEnter(jobject) y MonitorExit(jobject) funciones. Tal como suena MonitorEnter adquiere un candado en el proporcionado jobject, y MonitorExit libera el bloqueo en el proporcionado jobject.

NOTA: ¡Hay algunas trampas que debe tener en cuenta! Observe el penúltimo párrafo de MonitorEnterla descripción y el último párrafo de MonitorExitDescripción de la mezcla y combinación MonitorEnter/MonitorExit con otros mecanismos similares que, de otro modo, podría pensar que son compatibles.

Mira aquí

MonitorEnter

jint MonitorEnter (JNIEnv * env, jobject obj);

Ingresa al monitor asociado con el objeto Java subyacente al que hace referencia obj. Ingresa al monitor asociado con el objeto al que hace referencia obj. La referencia de obj no debe ser NULL. Cada objeto Java tiene un monitor asociado. Si el hilo actual ya posee el monitor asociado con obj, incrementa un contador en el monitor que indica el número de veces que este hilo ha entrado en el monitor. Si el monitor asociado con obj no es propiedad de ningún subproceso, el subproceso actual se convierte en el propietario del monitor, estableciendo el recuento de entradas de este monitor en 1. Si otro subproceso ya posee el monitor asociado con obj, el subproceso actual espera hasta que monitor se libera, luego intenta nuevamente obtener la propiedad.

No se puede salir de un monitor ingresado a través de una llamada de función MonitorEnter JNI utilizando la instrucción de máquina virtual Java monitorexit o un retorno de método sincronizado. Una llamada a la función MonitorEnter JNI y una instrucción de máquina virtual Java monitorenter pueden correr para ingresar al monitor asociado con el mismo objeto.

Para evitar interbloqueos, se debe salir de un monitor ingresado a través de una llamada de función MonitorEnter JNI mediante la llamada JNI MonitorSalir, a menos que la llamada DetachCurrentThread se use para liberar implícitamente los monitores JNI.

ENLACE:

Índice 217 en la tabla de funciones de la interfaz JNIEnv.

PARAMETROS:

env: el puntero de la interfaz JNI.

obj: un objeto de clase o objeto Java normal.

DEVOLUCIONES:

Devuelve “0” en caso de éxito; devuelve un valor negativo en caso de avería.

y

Monitorear Salir

jint MonitorSalir (JNIEnv * env, objeto de trabajo obj);

El subproceso actual debe ser el propietario del monitor asociado con el objeto Java subyacente al que hace referencia obj. El hilo disminuye el contador indicando el número de veces que ha entrado en este monitor. Si el valor del contador se vuelve cero, el hilo actual libera el monitor.

El código nativo no debe usar MonitorSalir para salir de un monitor ingresado a través de un método sincronizado o una instrucción de máquina virtual Java monitoreada.

ENLACE:

Índice 218 en la tabla de funciones de la interfaz JNIEnv.

PARAMETROS:

env: el puntero de la interfaz JNI.

obj: un objeto de clase o objeto Java normal.

DEVOLUCIONES:

Devuelve “0” en caso de éxito; devuelve un valor negativo en caso de avería.

Excepciones:

IllegalMonitorStateException: si el hilo actual no es propietario del monitor.

Entonces, el código C ++ en la pregunta que intentó usar pthreads debe cambiarse de la siguiente manera (el código asume que JNIEnv* puntero se adquirió de alguna manera de antemano en la forma típica de JNI):

class objectA

    jobject dataMutex;
    ... // everything else mentioned before


// called on c++ thread
void objectA :: poll()

    // You will need to aquire jniEnv pointer somehow just as usual for JNI
    jniEnv->MonitorEnter(dataMutex);

    ... // all the poll stuff from before

    jniEnv->MonitorExit(dataMutex);


// called on java thread
void objectA :: supplyData(JNIEnv* jni, jobject jthis, jobject data)

    // You will need to aquire jniEnv pointer somehow just as usual for JNI
    jniEnv->MonitorEnter(dataMutex);

    ... // all the supplyData stuff from before

    jniEnv->MonitorExit(dataMutex);

Felicitaciones a @Radiodef que proporcionó la respuesta. Desafortunadamente fue como un comentario. Esperé hasta la tarde del día siguiente para dar tiempo a que Radiodef respondiera, así que ahora lo estoy haciendo. Gracias Radiodef por proporcionar el empujón que necesitaba para solucionar este problema.

Eres capaz de reafirmar nuestra tarea exponiendo un comentario y dejando una puntuación te estamos eternamente agradecidos.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)


Tags :

Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *