當JNI遇到多線程--java對象如何被C++中的多個線程訪問?

      網(wǎng)友投稿 939 2025-04-05

      java中要訪問C++代碼時, 使用JNI是唯一選擇. 然而,在多線程的情況下, 可能出現(xiàn)以下問題:

      問題描述:

      一個java對象通過JNI調(diào)用DLL中一個send()函數(shù)向服務(wù)器發(fā)送消息,不等服務(wù)器消息到來就立即返回.同時

      把JNI接口的指針JNIEnv *env,和jobject obj保存在DLL中的變量里.

      一段時間后,DLL中的消息接收線程接收到服務(wù)器發(fā)來的消息,

      并試圖通過保存過的env和obj來調(diào)用先前的java對象的方法來處理此消息.

      然而,JNI文檔上說,JNI接口的指針JNIEnv*不能在c++的線程間共享,

      在我的程序中,如果接收線程試圖調(diào)用java對象的方法,程序會突然退出.

      不知道有沒有方法突破JNI接口的指針不能在多個c++線程中共享的限制?

      解決辦法:

      在?http://java.sun.com/docs/books/jni/html/pitfalls.html#29161?提到,

      JNI接口指針不可為多個線程共用,但是java虛擬機的JavaVM指針是整個jvm公用的. 于是,在DLL中可以調(diào)用:

      static JavaVM* gs_jvm;

      env->GetJavaVM(&gs_jvm); //來獲取JavaVM指針.獲取了這個指針后,在DLL中的另一個線程里,可以調(diào)用:

      JNIEnv *env;

      gs_jvm->AttachCurrentThread((void **)&env, NULL);

      (1)

      //java代碼:Test.java:

      import java.io.*;

      class Test implements Runnable

      {

      public int value = 0;

      private Thread tx=null;

      public Test()

      {

      tx=new Thread(this,"tx");

      }

      static

      {

      System.loadLibrary("Test");

      }

      public native void setEnev();

      public static void main(String args[])

      {

      Test t = new Test();

      t.setEnev();

      System.out.println("ok in java main");

      t.tx.start();

      try

      {

      Thread.sleep(10000000);

      }catch(Exception e)

      {

      System.out.println("error in main");

      }

      }

      public void run()

      {

      try

      {

      while(true)

      {

      Thread.sleep(1000);

      System.out.println(value);

      }

      }catch(Exception e)

      {

      System.out.println("error in run");

      }

      }

      }

      (2)

      //DLL代碼:Test.cpp:

      #include "test.h"

      #include

      #include

      static JavaVM *gs_jvm=NULL;

      static jobject gs_object=NULL;

      static int gs_i=10;

      void WINAPI ThreadFun(PVOID argv)

      {

      JNIEnv *env;

      gs_jvm->AttachCurrentThread((void **)&env, NULL);

      jclass cls = env->GetObjectClass(gs_object);

      jfieldID fieldPtr = env->GetFieldID(cls,"value","I");

      while(1)

      {

      Sleep(100);

      //在DLL中改變外面的java對象的value變量的值.

      env->SetIntField(gs_object,fieldPtr,(jint)gs_i++);

      }

      }

      JNIEXPORT void JNICALL Java_Test_setEnev(JNIEnv *env, jobject obj)

      {

      printf("come into test.dll/n");

      當JNI遇到多線程--java對象如何被C++中的多個線程訪問?

      //Returns “0” on success; returns a negative value on failure.

      int retGvm=env->GetJavaVM(&gs_jvm);

      //直接保存obj到DLL中的全局變量是不行的,應(yīng)該調(diào)用以下函數(shù):

      gs_object=env->NewGlobalRef(obj);

      HANDLE ht=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ThreadFun,0,NULL,NULL);

      printf("the Handle ht is:%d/n",ht);

      }

      C++ Java 任務(wù)調(diào)度

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔相應(yīng)法律責任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實后本網(wǎng)站將在24小時內(nèi)刪除侵權(quán)內(nèi)容。

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔相應(yīng)法律責任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實后本網(wǎng)站將在24小時內(nèi)刪除侵權(quán)內(nèi)容。

      上一篇:Excel2010中使用屏幕截圖功能輕松截取當前打開的程序窗口(excel2010怎么截屏)
      下一篇:為什么文件放在u盤里,放到別的電腦打不開?
      相關(guān)文章
      亚洲无码一区二区三区| 国产精品亚洲综合久久| 国产亚洲欧美日韩亚洲中文色 | 亚洲人成7777| 亚洲自偷自拍另类12p| 久久亚洲精品AB无码播放 | 亚洲一区二区三区91| 久久亚洲精品无码VA大香大香| 久久久久亚洲AV片无码| 亚洲av女电影网| 亚洲人成电影亚洲人成9999网| 亚洲国产精品免费视频| 亚洲人成亚洲精品| 久久亚洲私人国产精品vA| 亚洲精品高清国产麻豆专区| 亚洲最新黄色网址| 亚洲一区在线视频观看| 亚洲色中文字幕在线播放| 亚洲爆乳无码专区www| 成人亚洲国产精品久久| 亚洲国产中文v高清在线观看| 久久夜色精品国产亚洲av| 国产亚洲av人片在线观看| 国产亚洲精品无码成人| 亚洲日本在线看片| 亚洲国产精品白丝在线观看| 亚洲人成7777| 国产精品亚洲二区在线| 亚洲国产成人乱码精品女人久久久不卡 | 亚洲欧洲综合在线| 亚洲高清无在码在线电影不卡 | 亚洲av日韩综合一区二区三区| 噜噜综合亚洲AV中文无码| 亚洲第一永久AV网站久久精品男人的天堂AV| 国产AV无码专区亚洲AV琪琪| 国产成人毛片亚洲精品| 亚洲伊人久久精品影院| 亚洲AV日韩AV鸥美在线观看| 亚洲精品国产啊女成拍色拍 | 亚洲AV无码乱码在线观看富二代| 亚洲欧洲日产国码久在线观看 |