JNI调用Thread.currentThread为何对同一逻辑Java对象返回不同jobject
问题根因
你获取Java层Thread对象的逻辑本身没有错误,两次调用拿到的实际是同一个Java Thread对象,你看到的jobject指针值不等是JNI引用的特性导致的:
- JNI中传递到Native层的Java对象会被封装为引用类型,共分为局部引用、全局引用、弱全局引用三类。你通过
CallStaticObjectMethod返回的jobject属于局部引用,每次调用返回对象的局部引用时,JVM都会在当前线程的本地引用表中创建新的条目,所以哪怕指向同一个Java对象,两次返回的局部引用的指针值本身就会不同,属于正常现象。 - 你直接用
==比较两个jobject的方式是错误的:要判断两个JNI引用是否指向同一个Java对象,必须使用JNIEnv提供的IsSameObject方法,正确的判断逻辑如下:if (env->IsSameObject(t1, t2) == JNI_FALSE) { // 仅此处触发才代表指向不同的Java对象 }
代码隐含的其他问题
- 内存泄漏风险:你调用
env->GetStringUTFChars获取C风格字符串指针后,没有调用env->ReleaseStringUTFChars释放对应的内存,长时间运行会导致内存泄漏。 - 性能损耗:
FindClass、GetMethodID/GetStaticMethodID的调用开销较高,建议将类(需转为全局引用)、方法ID缓存起来,不需要每次调用都重复查找。
验证方案
你可以将判断逻辑替换为env->IsSameObject(t1, t2),也可以调用Thread.getId()方法输出两个对象的线程ID做验证,同一个Java线程的ID是固定相同的。
内容的提问来源于stack exchange,提问作者user14787178
相关产品推荐
相关产品推荐

