Java併發(一) 之 Java調用native文件

轉載備註地址:html

一、初始化環境介紹

1.1 環境介紹

CentOS Linux release 7.3.1611 (Core) OpenJDK 1.8java

1.2 環境配置

1.2.1 OpenJDK 安裝

yum -y install java-1.8.0-openjdk java-1.8.0-openjdk-devellinux

獲取java home:c++

dirname $(readlink $(readlink $(which java)))git

設置環境變量: vim /etc/profile.d/env_export.shvim

在新建的文件中填寫服務器

export JAVA_HOME=上面dirname命令獲取到的路徑,不要jre/bin最後這段jvm

export PATH=$PATH:$JAVA_HOME/bin模塊化

export CLASSPATH=.:$JAVA_HOME/jre/lib:$JAVA_HOME/lib:$JAVA_HOME/lib/tools.jar測試

1.2.2 gcc安裝

yum -y install gcc

二、Java 調用 .c文件

2.1 Java測試代碼

2.2 編譯Java代碼

一、上傳代碼至服務器

二、編譯.class文件

三、編譯.h 頭文件

2.3 查看.h頭文件

2.4 編寫.c文件

查看本身jni.h文件和jni_md.h文件地址

jni.h 文件

jni_md.h 文件

執行: gcc -fPIC -I /usr/lib/jvm/java-1.8.0-openjdk/include -I /usr/lib/jvm/java-1.8.0-openjdk/include/linux -shared -o libJucThreadNative.so threadNew.c

導入環境變量: 動態 c庫文件

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/home/thread/

執行 java com.lai.dian.JucThread

三、 .c文件回調 java

編譯一個.c文件經過jni 反射調用 java

執行命令: 編譯可執行文件

gcc -o threadNew threadNew.c -I /usr/lib/jvm/java-1.8.0-openjdk/include -I /usr/lib/jvm/java-1.8.0-openjdk/include/linux -L /usr/lib/jvm/java-1.8.0-openjdk/jre/lib/amd64/server -ljvm -pthread

執行文件: 編譯庫文件.so

gcc -fPIC -I /usr/lib/jvm/java-1.8.0-openjdk/include -I /usr/lib/jvm/java-1.8.0-openjdk/include/linux -shared -o libJucThreadNative.so threadNew.c

執行文件: 編譯java文件

從新上傳新的java文件,多了run方法

javac JucThread.java

步驟

Java 執行 JucThread這個類,初始化static System.loadLibrary( "JucThreadNative" );

調用Java_JucThread-start0() 這個方法,這個方法又經過jni 反射調用了run方法

四、注意事項

一、Java_com_lai_dian_JucThread_start0()方法就是你須要c程序定義的方法

二、gcc -fPIC -I /usr/lib/jvm/java-1.8.0-openjdk/include -I /usr/lib/jvm/java-1.8.0-openjdk/include/linux -shared -o libJucThreadNative.so threadNew.c 執行這個命令生成動態庫的時候必定要確認下本身的OpenJdk的路徑

-I /usr/lib/jvm/java-1.8.0-openjdk/include 導入 jni.h 頭文件

-I /usr/lib/jvm/java-1.8.0-openjdk/include/linux 導入jni_md.h頭文件

-fPIC: 選項做用於編譯階段,告訴編譯器產生與位置無關代碼(Position-Independent Code);這樣一來,產生的代碼中就沒有絕對地址了,所有使用相對地址,因此代碼能夠被加載器加載到內存的任意位置,均可以正確的執行。這正是共享庫所要求的,共享庫被加載時,在內存的位置不是固定的

-shared: Linux 下動態連接庫(shared object file,共享對象文件)的文件後綴爲.so,它是一種特殊的目標文件(object file),能夠在程序運行時被加載(連接)進來。使用動態連接庫的優勢是:程序的可執行文件更小,便於程序的模塊化以及更新,同時,有效內存的使用效率更高

-o: 生成指定文件

三、export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/home/thread/

導入動態庫的環境地址

四、每次修改 threadNew.c文件 須要從新編譯.so文件

五、參考地址

GCC生成動態連接庫(.so文件):-shared和-fPIC選項

六、總結

一、如何調用run方法?

thread -> start -> start0 ->native --> pthread_create(第三個參數是線程主體方法){ 這裏是經過jni反射調用,jvm不是這樣操做的}

int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg);

二、遺留問題jvm 如何經過hotspot c++ 方法調用java ?

七、demo地址

測試demo

相關文章
相關標籤/搜索