当前位置:网站首页>JNI-Thread中start方法的呼叫與run方法的回撥分析

JNI-Thread中start方法的呼叫與run方法的回撥分析

2020-11-06 21:07:00 itread01

### **前言** 在java程式設計中,執行緒Thread是我們經常使用的類。那麼建立一個Thread的本質究竟是什麼,本文就此問題作一個探索。 內容主要分為以下幾個部分 1.JNI機制的使用 2.Thread建立執行緒的底層呼叫分析 3.系統執行緒的使用 4.Thread中run方法的回撥分析 5.實現一個jni的回撥 ## **1.JNI機制的基本使用** 當我們new出一個Thread的時候,僅僅是建立了一個java層面的執行緒物件,而只有當Thread的start方法被呼叫的時候,一個執行緒才真正開始執行了。所以start方法是我們關注的目標 檢視Thread類的start方法 ```java public synchronized void start() { if (threadStatus != 0) throw new IllegalThreadStateException(); group.add(this); boolean started = false; try { start0(); started = true; } finally { try { if (!started) { group.threadStartFailed(this); } } catch (Throwable ignore) { } } } ``` Start方法本身並不複雜,其核心是start0(),真正地將執行緒啟動起來。 接著我們檢視start0()方法 ```java private native void start0(); ``` 可以看到這是一個native方法,這裡我們需要先解釋一下什麼是native方法。 眾所周知java是一個跨平臺的語言,用java編譯的程式碼可以執行在任何安裝了jvm的系統上。然而各個系統的底層實現肯定是有區別的,為了使java可以跨平臺,於是jvm提供了叫java native interface(JNI)的機制。當java需要使用到一些系統方法時,由jvm幫我們去呼叫系統底層,而java本身只需要告知jvm需要做的事情,即呼叫某個native方法即可。 例如,當我們需要啟動一個執行緒時,無論在哪個平臺上,我們呼叫的都是start0方法,由jvm根據不同的作業系統,去呼叫相應系統底層方法,幫我們真正地啟動一個執行緒。因此這就像是jvm為我們提供了一個可以作業系統底層方法的介面,即JNI,java本地介面。 在深入檢視start0()方法之前,我們先實現一個自己的JNI方法,這樣才能更好地理解start0()方法是如何呼叫到系統層面的native方法。 首先我們先定義一個簡單的java類 ```java package cn.tera.jni; public class JniTest { public native void jniHello(); public static void main(String[] args) { JniTest jni = new JniTest(); jni.jniHello(); } } ``` 在這個類中,我們定義了一個jniHello的native方法,然後在main方法中對其進行呼叫。 接著我們呼叫javac命令將其編譯成一個class檔案,但和平時不同,我們需要加一個-h引數,生成一個頭檔案 ``` javac -h . JniTest.java ``` 注意-h後面有一個.,意思是生成的標頭檔案,存放在當前目錄 這時我們可以看到在當前目錄下生成了2個新檔案 **JniTest.class**:JniTest類的位元組碼 **cn_tera_jni_JniTest.h**:.h標頭檔案,這個檔案是C和C++中所需要用到的,其中定義了方法的引數、返回型別等,但不包含實現,類似java中的介面,而java程式碼正是通過這個“介面”找到真正需要執行的方法。 我們檢視該.h檔案,其中就包含了jniHello方法的定義,當然需要注意到的是,這裡的方法名和.h檔案本身的命名是jni根據我們類的包名和類名確定出來的,不能修改。 ```c /* DO NOT EDIT THIS FILE - it is machine generated */ #

版权声明
本文为[itread01]所创,转载请带上原文链接,感谢
https://www.itread01.com/content/1604667783.html