【问题标题】:What is obj in MonitorEnter?MonitorEnter 中的 obj 是什么?
【发布时间】:2012-07-30 02:50:18
【问题描述】:

我不确定 MonitorEnter JNI 函数中的 obj 是什么。 obj 是作为本地函数中的参数传递还是要同步的共享变量? 我有一个名为缓冲区的变量,由两个线程共享。 这是我的代码。

JNIEXPORT void JNICALL Java_company_com_HelloActivity_setBuffer(JNIEnv *env, jobject obj, jstring jstr)
{
    char buf[256];

    int len = (*env)->GetStringLength(env, jstr);       
    (*env)->GetStringUTFRegion(env, jstr, 0, len, buf);
    (*env)->MonitorEnter(env, obj); // I don't think this is correct.
    strcat(buffer, buf); // buffer is declared as global char buffer[256];
    (*env)->MonitorExit(env, obj);
}

编辑: 这个怎么样? syncobj 在 Activity 中定义为静态 Object 并与另一个线程共享。

JNIEXPORT void JNICALL Java_company_com_HelloActivity_setBuffer(JNIEnv *env, jobject obj, jstring jstr, jobject syncobj)
{
    char buf[256];

    int len = (*env)->GetStringLength(env, jstr);       
    (*env)->GetStringUTFRegion(env, jstr, 0, len, buf);
    (*env)->MonitorEnter(env, syncobj);
    strcat(buffer, buf);
    (*env)->MonitorExit(env, syncobj);
}

【问题讨论】:

    标签: java-native-interface synchronize


    【解决方案1】:

    和这段Java代码中的一模一样:

    synchronized (syncobj) // = MonitorEnter(env, syncobj)
    {
      // ...
    } // = MonitorExit(env, syncobj)
    

    【讨论】:

      【解决方案2】:

      您的第一个 sn-p 相当于 synchronized(this),第二个 sn-p 是 synchronized(syncobj)。但只有当访问您的buffer 的另一个线程可以看到thissyncobj 时,这两个sn-ps 才有意义。恐怕另一个线程是本地线程。那为什么还要在本机代码中创建 buffer 呢?如果我是正确的,那么 MonitorEnter/Exit 是不必要的神秘 - 你可以使用它,但其他本机线程需要持有对 thissyncobj 的全局引用。本机锁定似乎是更清洁的解决方案。您正在锁定本机资源,而不是 JVM 资源。

      【讨论】:

      • 谢谢。但是,我不太清楚你的答案。我知道第一个 sn-p 是错误的解决方案。但是,我认为第二个 sn-p 是正确的解决方案。缓冲区是全局的。线程 A 在缓冲区中追加字符,线程 B 从缓冲区中取出字符。我只展示了附加部分。我在线程 A 中将 synobj 创建为静态并将其传递给附加部分。线程 B 从线程 A 获取 syobj 并将其传递给取出部分。
      • 我不知道原生线程是什么意思。我通过 new MyThread() 创建了线程,它是从 Java 中的 Thread 扩展而来的。
      • 那么缓冲区上的生产者(A)和消费者(B)都是Java线程?
      • 那么是的,第一个不会做,因为对于两个不同的线程,jobject obj 是两个不同的对象,因此不能确保相互访问。问题是,当生产者和消费者都是 Java 线程时,为什么你需要创建本地缓冲区,即使是这样,为什么简单的 synchronized native 方法对你来说还不够好。
      • 消费者检查输入,如果有,它将在循环中取出。它必须非常有效地完成。所以,我把缓冲区放在 C 语言中。如果缓冲区在 Java 中,我必须调用 JNI 函数来检查缓冲区。这就是原因。而且,生产者调用附加函数,消费者调用仅取出函数。消费者不调用上述代码 sn-p。第一个 sn-p 是荒谬的,因为 obj(this) 本身就是生产者线程。到目前为止,第二个 sn-p 效果很好。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-18
      • 2019-06-28
      • 2021-05-13
      • 1970-01-01
      • 2012-07-14
      相关资源
      最近更新 更多