網上大部分資料提供找到線程ID的方法多限於java程式內部線程對象的ID,而不是整個系統的線程ID,本來寄希望於 線程ID=進程ID+內部線程對象ID, 但實驗結果表明這個公式不成立,後來師兄說在windows下內部線程對象ID與線程ID有一一對應的關係,在linux下這種關係不固定,那就再換一種方式吧。
終於找到一種在linux下可以獲得java程式執行當前任務的線程ID,方法如下
1.編寫系統調用C檔案,實現gettid()方法
2.使用JNI用實現java對C的調用,即可在java中直接獲得gettid()返回當前線程ID
具體步驟
1.GetTid.java
public class GetTid {
static
{
System.loadLibrary("gettid");
}
public native int gettid();//本地方法聲明
public int getthreadId()
{
return gettid();
}
}
--------------------------------------------------------------------------
2.利用JNI編譯此JAVA檔案,產生GetTid.h(具體的方法可以參考我的另一篇博文——JNI調用)
3. gettid.c
#include <sys/syscall.h>
#include <sys/types.h>
#include <getopt.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <stdio.h>
#include <unistd.h>
#include <GetTid.h>
#define SYSCALL_NAME"gettid"
#ifndef _NR_gettid
#define _NR_gettid 224
#endif
JNIEXPORT int JNICALL Java_GetTid_gettid
(JNIEnv *env, jobject obj)
{
int sys_ret;
sys_ret=(pid_t)syscall(_NR_gettid);//使用系統調用獲得tid,雖然在linux終端中man gettid() 函數有使用方法,但是具體的實現還是要由自己來完成
printf("%d ",sys_ret);
return sys_ret;
}
--------------------------------------------------------------------------
4.makefile
libgettid.so:gettid.o
gcc -Wall -rdynamic -shared -o libgettid.so gettid.o
gettid.o:gettid.c GetTid.h
gcc -Wall -c gettid.c -I./ -I/usr/include -I/home/tina/workspace/tenantmanager/src/aspect -I/home/tina/jdk1.6.0_25/include -I/home/tina/jdk1.6.0_25/include/linux
---------------------------------------------------------------------------
5.編譯產生.so檔案,
再將該檔案拷到/usr/lib下,
然後更改系統內容變數檔案/etc/profile
添加export LD_LIBRARY_PATH=/home/usr/lib
經過這些步驟可以在其他的java程式中調用gettid()函數。
建議:我在實現過程中出現很多錯誤,一部分是JNI方面的,另一部分是關於編譯環境的,建議大家使用在linux環境下使用eclipse+CDT 編譯C或JAVA,因為複雜的項目,檔案之間有依賴性,單用javac 或GCC無法很好的處理依賴性,而eclipse在這一方面處理的很好,大家可以借用。
在此,多謝師兄們還有老公的協助。