Procházet zdrojové kódy

# feat:测试JNI的引用能否跨线程使用
经过测试,JNI的三种引用都可以跨线程使用
> 网络上有些资料说局部引用无法跨线程使用
> 猜测指的是在C/C++中无法跨线程使用,但在JVM中可以跨线程使用,JNI返回的可能是拷贝后数据,不是原生的C/C++中的数据

yangyi před 2 týdny
rodič
revize
0572acdc58

+ 1 - 1
c/reference/JNI_localReference.c

@@ -5,7 +5,7 @@ JNIEXPORT jobject JNICALL Java_space_anyi_jni_reference_LocalReferenceTest_getPe
     //2.获取对应的构造方法
     jmethodID constructor = (*env)->GetMethodID(env, class_Person, "<init>", "(Ljava/lang/String;I)V");
     //3.创建对象
-    jstring name = (*env)->NewStringUTF(env, "杨逸");
+    jstring name = (*env)->NewStringUTF(env, "杨逸-局部引用");
     jobject person = (*env)->NewObject(env, class_Person, constructor,name,18);
     return person;
 }

+ 59 - 10
src/main/java/space/anyi/jni/reference/Main.java

@@ -11,14 +11,25 @@ import java.util.Objects;
  */
 public class Main {
     static {
-        System.load("E:\\tmp\\JNI_learn\\c\\reference\\JNI_globalReference.dll");
-        System.load("E:\\tmp\\JNI_learn\\c\\reference\\JNI_weakGlobalReference.dll");
-        System.load("E:\\tmp\\JNI_learn\\c\\reference\\JNI_localReference.dll");
+        System.load("/home/yangyi/JNI_learn/c/reference/JNI_globalReference.so");
+        System.load("/home/yangyi/JNI_learn/c/reference/JNI_weakGlobalReference.so");
+        System.load("/home/yangyi/JNI_learn/c/reference/JNI_localReference.so");
     }
     public static void main(String[] args) {
+        //测试全局引用的基本使用
         //GlobalReferenceTest.test();
+        //测试全局引用是否会被JVM进行GC
+//        GlobalReferenceTest.testJVMGC();
+        //测试全局引用是否能跨线程使用
+//        GlobalReferenceTest.testThread();
+        //测试弱全局引用是否会被JVM进行GC
         //WeakGlobalReferenceTest.testJVMGC();
-        LocalReferenceTest.test();
+        //测试弱全局引用能否跨线程使用
+        WeakGlobalReferenceTest.testThread();
+        //测试局部引用的基本使用
+//        LocalReferenceTest.test();
+        //测试局部引用能否跨线程使用
+//        LocalReferenceTest.testThread();
     }
 }
 class LocalReferenceTest{
@@ -47,7 +58,18 @@ class LocalReferenceTest{
             localReferenceTest.getPerson();
         }
     }
-
+    /**
+     * 测试局部引用能否跨线程使用
+     */
+    static void testThread(){
+        Person person = localReferenceTest.getPerson();
+        System.out.println("Thread.currentThread().getName() = " + Thread.currentThread().getName());
+        new Thread(()->{
+            //全局引用跨线程使用
+            System.out.println("Thread.currentThread().getName() = " + Thread.currentThread().getName());
+            System.out.println("person = " + person);
+        }).start();
+    }
     /**
      * 在JNI中创建一个局部引用,并返回对象
      * @return {@code Person }
@@ -103,6 +125,20 @@ class GlobalReferenceTest{
             globalReferenceTest.getPersonHandler();
         }
     }
+
+    /**
+     * 测试全局引用能否跨线程使用
+     */
+    static void testThread(){
+        long personHandler = globalReferenceTest.getPersonHandler();
+        Person person = globalReferenceTest.getPerson(personHandler);
+        System.out.println("Thread.currentThread().getName() = " + Thread.currentThread().getName());
+        new Thread(()->{
+            //全局引用跨线程使用
+            System.out.println("Thread.currentThread().getName() = " + Thread.currentThread().getName());
+            System.out.println("person = " + person);
+        }).start();
+    }
     /**
      * 在JNI中创建一个全局引用,并返回句柄
      * @return long 全局引用的句柄
@@ -135,7 +171,7 @@ class GlobalReferenceTest{
     native void freePerson(long handler);
 }
 class WeakGlobalReferenceTest {
-    static WeakGlobalReferenceTest globalWeakReferenceTest = new WeakGlobalReferenceTest();
+    static WeakGlobalReferenceTest weakGlobalReferenceTest = new WeakGlobalReferenceTest();
 
     /**
      * 测试在JVM中使用JNI创建的对象全局弱引用
@@ -146,15 +182,15 @@ class WeakGlobalReferenceTest {
      */
     static void test(){
         //获取全局弱引用的句柄
-        long personHandler = globalWeakReferenceTest.getPersonHandler();
+        long personHandler = weakGlobalReferenceTest.getPersonHandler();
 
         //根据句柄获取全局引用对象
-        Person person = globalWeakReferenceTest.getPerson(personHandler);
+        Person person = weakGlobalReferenceTest.getPerson(personHandler);
         System.out.println("person.getName() = " + person.getName());
         System.out.println("person.getAge() = " + person.getAge());
         System.out.println(person);
         //释放全局弱引用
-        globalWeakReferenceTest.freePerson(personHandler);
+        weakGlobalReferenceTest.freePerson(personHandler);
     }
 
     /**
@@ -166,9 +202,22 @@ class WeakGlobalReferenceTest {
      */
     static void testJVMGC(){
         while (true){
-            globalWeakReferenceTest.getPersonHandler();
+            weakGlobalReferenceTest.getPersonHandler();
         }
     }
+    /**
+     * 测试弱全局引用能否跨线程使用
+     */
+    static void testThread(){
+        long personHandler = weakGlobalReferenceTest.getPersonHandler();
+        Person person = weakGlobalReferenceTest.getPerson(personHandler);
+        System.out.println("Thread.currentThread().getName() = " + Thread.currentThread().getName());
+        new Thread(()->{
+            //全局引用跨线程使用
+            System.out.println("Thread.currentThread().getName() = " + Thread.currentThread().getName());
+            System.out.println("person = " + person);
+        }).start();
+    }
     /**
      * 在JNI中创建一个全局引用,并返回句柄
      * @return long 全局弱引用的句柄