首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从新的JNI线程通知Java

从新的JNI线程通知Java
EN

Stack Overflow用户
提问于 2021-11-08 12:13:49
回答 1查看 69关注 0票数 1

我编写了一个调用JNI的Java程序,在JNI中它创建了一个"JNICallback“线程,并在其中执行env-attachCurrentThreadAsDaemon()

我的目标是从Java线程通知,这是另一个纯JNICallback线程。我使用static final Object作为同步,做一些标准的事情,比如synchronized -> wait, synchronized -> notifyAll。如果我在Eclipse下运行它,一切都会正常工作。

但是如果我将其导出为"runnable jar文件“并在相同的JVM下运行,我会看到我的JNI程序调用monitorEnter, notifyAll, monitorExit时没有错误,但是Java没有通知。在调试器中,我看到来自JNI和Java的同一个对象使用了不同的ObjectId,这对我来说很可疑(下面代码中的名称是onConnectEvent )我甚至将通知代码从JNI转移到Java,并使用JNI中的静态void方法调用,在Java语言中执行synchronize->notifyAll,但这只显示等待线程在不同的ObjectId上等待,所以我猜这就是原因。

代码语言:javascript
复制
...
    static final Object onConnectEvent = new Object();
...
    Thread dogServerConnect,...;
...
    public MainClass(){
        dogServerConnect = runDog(new ServerConnectionWatchDog(), "onServerConnect");
        someJNIstuffPlusNewThreadsCreation();
...
    
    static void onJNICallbackEvent(int type) {
        switch (type) {
        case 1 -> {
            synchronized(onConnectEvent) {
                onConnectEvent.notifyAll();
                 ^^^^^ got to this line from JNI, just fine
            }
...
    class ServerConnectionWatchDog implements Runnable {
        @Override
        public void run() {
            while(true)
                synchronized(onConnectEvent) {
                    try {
                        onConnectEvent.wait();
                        for (var l : listeners) {
^^^^^^^^^^^^^^^^^^^^^^^^^ never come to this line
...

同样,这在Eclipse下工作得很好,但由于某些原因,作为单独的jar文件失败。为什么相同的最终静态对象可以有不同的实例it用于不同的线程,或者现在很好?

我的意思是,对于等待线程,Eclipse显示"waiting for: Object (id=48)“,对于执行"notifyAll”之前的本机线程,它显示“拥有: Object (id=50)”。也许这是因为我手动暂停了等待线程,以查看对象id (然后再次运行它,这不是原因),我可能会错过什么?

EN

Stack Overflow用户

回答已采纳

发布于 2021-11-17 21:43:12

在Android的常见问题解答中找到了答案:why didn't FindClass find my class。虽然我的环境不是Android,但它仍然有意义。问题是env->FindClass展开一个Java堆栈来找到一个调用者类并使用它的类加载器。对于在JNI中启动的本机线程,Java堆栈是空的。因此,这给了我们一个唯一的选择,要么在创建本机线程之前获取对所需类的全局引用,要么在同一位置获取对其类加载器的引用,然后使用保存的classLoader中的FindClass,这是比较困难的。这个解决方案可以防止Eclipse JarRsrcLoader创建重复的静态对象。也许有人会说,在JNI中新创建的本机线程中执行env->FindClass是一个糟糕的设计,至少要谨慎使用。

票数 0
EN
查看全部 1 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69883285

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档