2015-05-19 75 views
1

我正在使用通過JNA加載的C++庫。我試圖多線程我的Java程序,但C++庫不是線程安全的,並且使庫在線程安全目前不是一個現實的選擇。我知道一次只能加載一個庫的一個副本,但我認爲如果我複製了庫文件併爲每個線程擁有一個副本,那麼我會沒事的。但是,我似乎發現情況並非如此:這裏有兩個測試。第一個加載一個庫,執行一個方法,加載一個庫的副本,並執行相同的方法:它給我一個錯誤。第二個簡單的加載一個庫並且執行兩次這個方法,並且不會引起任何問題。JNA加載同一個庫的多個副本

是沒可能加載庫的兩個副本,甚至作爲兩個單獨的文件(如果沒有,有另一種方式來做到這一點?)的錯誤看起來像*** Error in `java': free(): invalid pointer: 0x00007feb9001eba0 ***的錯誤也總是發生在測試結束(好像方法都做工精細,然後當測試結束我的錯誤)

public class NativeLibraryTest { 

    @Test 
    public void test() throws IOException { 
     final String libPath = "libjna.so"; 
     final MyLibrary library = Native.loadLibrary(libpath, MyLibrary.class); 
     library.doThing(); 
     final String libPath2 = "libjna_copy.so"; 
     final MyLibrary library2 = Native.loadLibrary(libpath2, MyLibrary.class); 
     library2.doThing(); 
     // get an error at the end of the test 
    } 

    @Test 
    public void testSingle() throws IOException { 
     final String libPath = "libjna.so"; 
     final MyLibrary library = Native.loadLibrary(libpath, MyLibrary.class); 
     library.doThing(); 
     library.doThing(); 
     // no error 
    } 

} 

感謝

回答

1

對於JNI無法加載同一個庫一次以上,即使是重命名。要執行的本地方法僅由其名稱標識,庫名稱將被忽略。

如果要加載兩個庫,需要兩個具有不同名稱或程序包位置的Java類,爲每個庫定義JNI接口。 然後你必須創建兩個由JNI編譯器生成的頭文件的實現。

無論如何取決於非線程安全庫的實現這可能仍然會造成麻煩。

恕我直言,唯一安全的方法是使用多個進程實現您的應用程序,然後使用進程間通信。一個主進程和兩個使用非線程安全庫的工作進程。