[英]How main thread created by Java
我是 Java 技术的新手。 我知道在Java中只有两种方法可以创建Thread
所以这只是创建Thread
两种方法。 但是当我们用主 JVM 启动我们的程序时,启动了一个主Thread
。 我认为即使 JVM 也必须遵循创建主Thread
的规则,即创建主线程 JVM 必须扩展 Thread 类或实现Runnable
。
public class MainThreadExample {
public static void main(String[] args) {
Thread t=Thread.currentThread();
System.out.println(t.getName());
}
}
我尽了最大努力,但无法知道 JVM 如何创建这个主要对象。 当我完全通过主类( sun.tool.jar
)时,我知道这是负责主线程的类。但是在谷歌搜索了这么多网页后无法得到它。 所以请帮忙,如果可能的话,也请参考我的例子或链接。
PS:我正在学习 Java 技术,我不应该担心他们是如何创建 main 的,这只是一个设计问题。 但我认为这是一个合乎逻辑的问题
java.lang.Thread
的实例不是线程; 它可用于表示 JVM 中的执行线程,但 JVM 完全有能力创建线程而根本不使用Thread
类。
这就是主线程发生的事情:JVM 创建它,然后创建一个java.lang.Thread
实例来表示它。
在 Hotspot JVM 中,在src/share/vm/runtime/thread.hpp
和src/share/vm/runtime/thread.cpp
定义的Threads
类中有很多与线程相关的代码。 JVM 的启动调用静态Threads::create_vm
函数,该函数已经在操作系统设置的线程中运行。 在该函数中,我们发现:
(src/share/vm/runtime/thread.cpp)
3191 // Attach the main thread to this os thread
3192 JavaThread* main_thread = new JavaThread();
3193 main_thread->set_thread_state(_thread_in_vm);
3194 // must do this before set_active_handles and initialize_thread_local_storage
3195 // Note: on solaris initialize_thread_local_storage() will (indirectly)
3196 // change the stack size recorded here to one based on the java thread
3197 // stacksize. This adjusted size is what is used to figure the placement
3198 // of the guard pages.
3199 main_thread->record_stack_base_and_size();
3200 main_thread->initialize_thread_local_storage();
JavaThread
类显然用于簿记; 它将 OS 或 VM 线程与 Java Thread 对象相关联。 Java 对象显然还不存在。 然后代码继续初始化各种其他东西,后来仍然在同一个函数中,我们发现:
3335 // Initialize java_lang.System (needed before creating the thread)
3336 if (InitializeJavaLangSystem) {
3337 initialize_class(vmSymbols::java_lang_System(), CHECK_0);
3338 initialize_class(vmSymbols::java_lang_ThreadGroup(), CHECK_0);
3339 Handle thread_group = create_initial_thread_group(CHECK_0);
3340 Universe::set_main_thread_group(thread_group());
3341 initialize_class(vmSymbols::java_lang_Thread(), CHECK_0);
3342 oop thread_object = create_initial_thread(thread_group, main_thread, CHECK_0);
3343 main_thread->set_threadObj(thread_object);
3344 // Set thread status to running since main thread has
3345 // been started and running.
3346 java_lang_Thread::set_thread_status(thread_object,
3347 java_lang_Thread::RUNNABLE);
换句话说,我们把它初始化System
, ThreadGroup
和Thread
类,然后创建实例Thread
通过引用thread_object
(线3342),并设置Thread
实例主JavaThread
。
如果你想知道create_initial_thread
做了什么,显然它分配了 Thread 实例,在 Thread 实例的私有eetop
字段中存储了一个指向JavaThread
(C++) 对象的指针,将线程优先级字段设置为正常,调用Thread(ThreadGroup group,String name)
构造函数,并返回实例:
967 // Creates the initial Thread
968 static oop create_initial_thread(Handle thread_group, JavaThread* thread, TRAPS) {
969 klassOop k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_Thread(), true, CHECK_ NULL);
970 instanceKlassHandle klass (THREAD, k);
971 instanceHandle thread_oop = klass->allocate_instance_handle(CHECK_NULL);
972
973 java_lang_Thread::set_thread(thread_oop(), thread);
974 java_lang_Thread::set_priority(thread_oop(), NormPriority);
975 thread->set_threadObj(thread_oop());
976
977 Handle string = java_lang_String::create_from_str("main", CHECK_NULL);
978
979 JavaValue result(T_VOID);
980 JavaCalls::call_special(&result, thread_oop,
981 klass,
982 vmSymbols::object_initializer_name(),
983 vmSymbols::threadgroup_string_void_signature(),
984 thread_group,
985 string,
986 CHECK_NULL);
987 return thread_oop();
988 }
现在,这就是 Hotspot VM 所做的。 其他实现,如 IBM J9、Oracle JRockit 或 Azul Zing 可能会做类似的事情。
我相信确切的机制是特定于 JVM 的。 规范有点模糊,但Thread
Javadoc提供了以下内容:
当 Java 虚拟机启动时,通常会有一个非守护线程(通常调用某个指定类的名为
main
的方法)。
这似乎没有指定如何映射到Thread
类的实例。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.