关于使用JNI的注意事项

原文来自于官方安卓开发文档中使用JNI相关注意事项,但同样也适用于其他情况下的JNI相关开发:

https://developer.android.com/training/articles/perf-jni

其中比较重要的是JNI与线程,以下是我对这一部分的翻译:

JNI之线程篇

所有的线程都是由Linux内核进行规划的Linux线程(注:因为这篇文章是出自安卓开发,所以这么说). 它们通常都是产生于Managed code(关于什么是Managed code:https://en.wikipedia.org/wiki/Managed_code),比如类似于Thread.start()这样的Managed code,但是它们也可以在别的地方被创建然后再被添加到Java虚拟机(JavaVM)中 . 比如说,一个线程如果是通过pthread_create() 或者是 std::thread来开启的话,那这个线程可以通过AttachCurrentThread() or AttachCurrentThreadAsDaemon()函数来添加到Java虚拟机。在这个线程被添加到Java虚拟机之前,这个线程将不会拥有JNIEnv变量并且不能使用任何JNI功能。

通常来说,使用Thread.start()来创建线程是比较好的做法。这样的话能确保你的线程有足够的栈空间,能确保你的线程在正确的线程组里面(ThreadGroup),而且能确保你使用的类加载器(ClassLoader)和你的Java代码所使用的类加载器是相同的。还没完,Java代码创建的线程相比于用本地(native)代码创建的线程能更好地被命名,这样的话在debug的时候会更方便。

将一个由本地(native)代码创建的线程添加到Java虚拟机中时,一个相应的java.lang.Thread对象将会被创建并且被添加大"main"线程组中(ThreadGroup)。对一个已经被添加到Java虚拟机中的线程调用AttachCurrentThread()方法的话并不会起什么作用。

通过JNI添加到虚拟机中的线程在它们退出之前必须调用DetachCurrentThread()。

 

翻译结束,其中最重要的就是在JNI中创建新的线程的话必须将这个线程添加(attach)到虚拟机中,然后获得一个专属于这个线程的JNIEnv变量,才能进行后续的调用,如果不进行线程的添加而且直接让多个线程共享一个JNIEnv变量来进行操作的话就会出现

EXCEPTION_ACCESS_VIOLATION (0xc0000005)的错误

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值