Android JNI - 线程同步

贵有恒,何必三更起、五更眠、最无益,只怕一日曝、十日寒。这篇文章主要讲述Android JNI - 线程同步相关的知识,希望能为你提供帮助。
我有一个本机C ++代码,我通过JNI从android调用。

JNIEXPORT void JNICALL java_com_myapp_CApi_setFoo(JNIEnv *env, jobject thiz, jstring foo) { const char * fooStr = env-> GetStringUTFChars(foo, 0); MyCApiSetFoo(fooStr); env-> ReleaseStringUTFChars(foo, fooStr); }JNIEXPORT jstring JNICALL Java_com_myapp_CApi_getFoo(JNIEnv *env, jobject thiz) { return env-> NewStringUTF(MyCApiGetFoo()); }

一切正常。但是,getset方法可以从不同的线程访问,在这种情况下,有时get在set之前被调用。如何解决线程同步问题?我无法编辑底层API。
我在考虑在每个JNI方法中使用std::unique_lock并创建我将锁定的全局std::mutex变量。这是一个好方法,还是有一些“标准”JNI方式(我发现有可以从env访问的监视器)。
我也经常调用get(它是在OpenGL渲染循环期间),因此性能至关重要。
答案【Android JNI - 线程同步】锁定互斥锁的JNI方式是MonitorEnter/MonitorExit
也就是说,您可以从java代码输入java synchronized块所需的监视器。
JNIEXPORT void JNICALL Java_com_myapp_CApi_setFoo(JNIEnv *env, jobject thiz, jstring foo) { const char * fooStr = env-> GetStringUTFChars(foo, 0); env-> MonitorEnter(thiz); // same effect as synchronized(thiz) { ... MyCApiSetFoo(fooStr); env-> MonitorExit(thiz); env-> ReleaseStringUTFChars(foo, fooStr); }JNIEXPORT jstring JNICALL Java_com_myapp_CApi_getFoo(JNIEnv *env, jobject thiz) { env-> MonitorEnter(thiz); auto res = MyCApiGetFoo(); env-> MonitorExit(thiz); return env-> NewStringUTF(res); }

您可以使用任何对象锁定,如果没有提供足够级别的锁定粒度,则不必是thiz
或者,如果您只需要锁定C ++代码内部的结构,请使用带有std::mutex的静态lock_guard

    推荐阅读