У меня нет ссылки на источник jdk или java threading. Возможно, если бы вы предоставили его, я мог бы решить вашу проблему.
Однако, что я собрал из вашего вопроса: «Как ссылка Thread.h на Thread.cpp?» Если это то, что вы просите, тогда подумайте об этом так:
Thread.h просто содержит кучу объявлений. Аналогично интерфейсу Java. Thread.c содержит реализацию этого интерфейса.
Что касается моего второго предположения относительно того, что вы спрашиваете: «Как Java создает собственный поток?».
Если бы мне пришлось взять огромный догадку на Java создает поток на Windows, я бы сказал, что определение либо написаны с использованием WINAPI (только для Windows) или СТЛ C++ (портативный):
Предположим, у вас есть a java Тип резьбы:
public class Threading {
static{ System.LoadLibrary("Threading"); }
private Runnable r = null;
private native void StartNativeThread(Runnable r);
public Threading(Runnable r) {
this.r = r;
}
public void start() {
StartNativeThread(this.r);
}
}
Вышеупомянутый класс передается в свой конструктор.Когда вы вызываете start, он вызывает собственную функцию «StartNativeThread», и эта функция будет принимать runnable в качестве параметра. На стороне C++ он создаст поток, и этот поток вызовет Runnable.run, который он получил со стороны java.
WINAPI-C++:
//object that will hold all thread information.
struct ThreadParams
{
JNIEnv* env;
jobject runnable;
};
//function that the thread will call.
DWORD __stdcall RunnableThreadProc(void* ptr)
{
ThreadParams* p = reinterpret_cast<ThreadParams*>(ptr); //get our thread info from the parameter.
JNIEnv* env = p->env; //grab our env.
jobject runnable = p->runnable; //grab our runnable object.
delete p; //since we allocated on the heap using new, we must delete from the heap.
//this is because c++ does not have garbage collection.
jclass RunnableInterface = env->GetObjectClass(runnable); //get our java runnable interface instance.
jmethodID Run = env->GetMethodID(RunnableInterface, "run","()V"); //get the run method function pointer.
env->CallObjectMethod(RunnableInterface, Run); //call RunnableInterface.run();
}
JNIEXPORT void JNICALL Java_JNIExample_StartNativeThread(JNIEnv* env, jobject obj, jobject runnable)
{
ThreadParams* ptr = new ThreadParams(); //create an object to store our parameters.
ptr->env = env; //store the env parameter.
ptr->runnable = runnable; //store the runnable object.
//create a thread that calls "RunnableThreadProc" and passes it "ptr" as a param.
CreateThread(0, 0, RunnableThreadProc, reinterpret_cast<void*>(ptr), 0, 0);
}
Теперь выше выглядит довольно сложным, чтобы быть полностью честным, но это то, что WINAPI есть. Это API, написанный для окон на языке C.
Если у вас есть компилятор C++ x11 и вы хотите избежать winapi и использовать STL-C++, это можно сделать в пару строк. Предположим, что у нас есть один и тот же класс Java, как указано выше, то наша функция становится:
JNIEXPORT void JNICALL Java_JNIExample_StartNativeThread(JNIEnv* env, jobject obj, jobject runnable)
{
std::thread([&]{
jclass RunnableInterface = env->GetObjectClass(runnable);
jmethodID Run = env->GetMethodID(RunnableInterface, "run","()V");
env->CallObjectMethod(RunnableInterface, Run);
}).detach();
}
Обратите внимание, что [&]{....}
является лямбда-функции. Это означает функцию, которая может быть создана внутри другой функции или параметра.
выше также могут быть переведены/эквивалентно:
void ThreadProc(JNIEnv* env, jobject runnable)
{
jclass RunnableInterface = env->GetObjectClass(runnable);
jmethodID Run = env->GetMethodID(RunnableInterface, "run","()V");
env->CallObjectMethod(RunnableInterface, Run);
}
JNIEXPORT void JNICALL Java_JNIExample_StartNativeThread(JNIEnv* env, jobject obj, jobject runnable)
{
std::thread(ThreadProc, env, obj).detach();
}
Теперь реализации других вещей, как стоп и пауза так же легко. Вы просто делаете это на стороне java внутри вашего runnable. ИЛИ вы можете сделать это на стороне C++, используя WINAPI TerminateThread
и WaitObject
и тому подобное. ИЛИ, если вы решите использовать STL-C++, вы должны использовать std::condition_variable
.
Я надеюсь, что это прояснит некоторые вещи. Если у вас есть дополнительные вопросы, вы можете просто оставить комментарий или создать новый поток. Вам решать. В противном случае, если я что-то пропустил или неправильно понял ваш вопрос, пожалуйста, проясните его.
EDIT .. Так что для фактической реализации, мы можем видеть, что Thread.c включает jvm.h. Таким образом, мы должны найти jvm.h и jvm.cpp.
Быстрый поиск придумывает:
Thread.h: http://hg.openjdk.java.net/jdk7/jdk7/jdk/file/00cd9dc3c2b5/src/share/native/java/lang/Thread.c
JVM.h: http://hg.openjdk.java.net/jdk7/jdk7/hotspot/file/tip/src/share/vm/prims/jvm.h
JVM.cpp: http://hg.openjdk.java.net/jdk7/jdk7/hotspot/file/9b0ca45cd756/src/share/vm/prims/jvm.cpp
Если мы теперь искать какой-либо из функции из thread.c .. В thread.c мы видим, что start0 сопоставляется с JVM_StartThread, а все другие функции потока сопоставляются с JVM_XXXXSomeThreadFunc ...
Теперь мы должны искать эти JVM_-функции в JVM.h и JVM.cpp. Найдя, у вас есть источник того, как все это делается.
Здесь есть много вопросов XY. Что вы на самом деле пытаетесь открыть? – EJP