#include <jni.h>
#include <stdio.h>
#include <unistd.h> // for sleep()
#include <pthread.h>
#include <time.h>
#include <stdlib.h>
// 文件全局变量
static JavaVM *jvm = NULL;
static unsigned call_count = 0;
void *thread_fun(void *arg)
{
jint res = 0;
jclass clazz;
jmethodID dateConstructorID;
jmethodID getHoursID;
jmethodID getMinutesID;
jmethodID getSecondsID;
JNIEnv *env;
// JavaVM还没有初始化
if(jvm == NULL) {
printf("Obtain JavaVM error!\n");
goto detach;
}
printf("thread_fun have been called %d times!\n", ++call_count);
// 将线程附加到JavaVM上
res = (*jvm)->AttachCurrentThread(jvm, (void **)&env, NULL);
if(res < 0) {
printf("AttachCurrentThread errir!\n");
goto detach;
}
// 下面开始查找Date类以及获取时间的方法ID
clazz = (*env)->FindClass(env, "java/util/Date");
if(clazz == NULL) {
printf("FindClass error!\n");
goto detach;
}
getHoursID = (*env)->GetMethodID(env, clazz, "getHours", "()I");
if(getHoursID == NULL) {
printf("getHoursID error!\n");
goto detach;
}
getMinutesID = (*env)->GetMethodID(env, clazz, "getMinutes", "()I");
if(getMinutesID == NULL) {
printf("getMinutesID error!\n");
goto detach;
}
getSecondsID = (*env)->GetMethodID(env, clazz, "getSeconds", "()I");
if(getSecondsID == NULL) {
printf("getSecondsID error!\n");
goto detach;
}
// 获取构造函数方法ID
dateConstructorID = (*env)->GetMethodID(env, clazz, "<init>", "()V");
if(dateConstructorID == NULL) {
printf("dateConstructorID error!\n");
goto detach;
}
// 调用Date的构造函数来创建一个对象
jobject dateObject = (*env)->NewObject(env, clazz, dateConstructorID);
if(dateObject == NULL) {
printf("call constructor error!\n");
goto detach;
}
// 调用方法获取时间值
jint hours = (*env)->CallIntMethod(env, dateObject, getHoursID);
jint minutes = (*env)->CallIntMethod(env, dateObject, getMinutesID);
jint seconds = (*env)->CallIntMethod(env, dateObject, getSecondsID);
detach:
// 下面需要括号括起来,不然会报错:a label can only be part of a statement and a declaration is not a statemen
{
jthrowable exc = (*env)->ExceptionOccurred(env);
if(exc) {
(*env)->ExceptionDescribe(env);
(*env)->ExceptionClear(env);
(*jvm)->DetachCurrentThread(jvm);
pthread_exit((void *)-1);
}
}
printf("Now Time: %02d:%02d:%02d\n", hours, minutes, seconds);
pthread_exit((void *)0);
}
int main(int argc, char **argv)
{
JNIEnv *env;
int i = 0;
jint res = 0;
pthread_t tid;
srand(time(0));
// 初始化虚拟机参数
JavaVMInitArgs vm_args;
JavaVMOption options[1];
options[0].optionString = "-Djava.class.path=$JAVA_HOME/";
vm_args.version = JNI_VERSION_1_8;
vm_args.options = options;
vm_args.nOptions = 1;
vm_args.ignoreUnrecognized = JNI_FALSE;
// 创建虚拟机
res = JNI_CreateJavaVM(&jvm, (void **)&env, &vm_args);
if(res < 0) {
printf("Can't create Java VM\n");
return -1;
}
for(i = 0; i < 10; i++) {
res = pthread_create(&tid, NULL, thread_fun, NULL);
if(res != 0) {
printf("#%d, pthread_create error!\n", i);
continue;
}
// 随机休眠1-5秒
unsigned sleepTime = 1 + (random() % 4);
printf("go to sleep %d seconds!\n", sleepTime);
sleep(sleepTime);
}
return 0;
}