当前位置: 首页 > 面试题库 >

Java如何创建主线程

乌修筠
2023-03-14
问题内容

我是Java技术的新手。我知道Thread在Java中只有两种创建方式

  • 扩展线程类
  • 实施可运行接口

因此,这只是两种创建方法Thread。但是,当我们使用主JVM启动程序时,它启动了一个main
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)时,我知道这是负责主线程的类。但是在Google中搜索了如此多的网页后,无法找到它。因此,请提供帮助,如有可能,请同时参考示例或链接。

PS:我正在学习Java技术,我不应该为他们如何创建主要语言而烦恼,这全是设计问题。但我认为这是一个合乎逻辑的问题


问题答案:

的实例java.lang.Thread不是线程;它可以用来表示JVM中的执行线程,但是JVM完全能够创建线程而无需使用Thread类。

这就是主线程发生的情况:JVM创建了它,并创建了一个实例java.lang.Thread来表示它。

在Hotspot JVM
Threads中,src/share/vm/runtime/thread.hppand中定义的类中有很多与线程相关的代码src/share/vm/runtime/thread.cpp。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);

换句话说,我们把它初始化SystemThreadGroupThread类,然后创建的实例Thread通过参考thread_object(线3342),并设定了Thread用于主实例JavaThread

如果您想知道它的create_initial_thread作用,那么显然它会分配Thread实例,将指向JavaThread(C
++)对象的指针存储在Thread实例的私有eetop字段中,将线程优先级字段设置为normal,调用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)可能也会执行类似的操作。



 类似资料:
  • 本文向大家介绍如何创建线程池 ?相关面试题,主要包含被问及如何创建线程池 ?时的应答技巧和注意事项,需要的朋友参考一下 在《阿里巴巴 Java 开发手册》“并发处理”这一章节,明确指出线程资源必须通过线程池提供,不允许在应用中自行显示创建线程。 为什么呢? 使用线程池的好处是减少在创建和销毁线程上所消耗的时间以及系统资源开销,解决资源不足的问题。如果不使用线程池,有可能会造成系统创建大量同类线程而

  • 你不知道如何在JOOQ(Java)中创建主键吗?我需要的只是得到正确的创建表字符串。我还没有这段代码(使用SQLDialect。MYSQL): 输出(来自字符串生成器): 我需要的是设置主键以获得正确的输出: 不使用execute()是否可能?因为我只需要它作为字符串,所以我想再次使用only getSQL()命令。。。 我发现了类似这样的东西:DSL。主密钥(“id”); 但我无法将它与rest

  • 问题内容: 我想通过Java在Kafka(kafka_2.8.0-0.8.1.1)中创建一个主题。如果我在命令提示符下创建一个主题,并且如果我通过java api推送消息,它也可以正常工作。但是我想通过java api创建一个主题。经过长时间的搜索,我发现了以下代码, 我尝试了上面的代码,它表明创建了主题,但是无法在该主题中推送消息。我的代码有什么问题吗?还是通过其他方式实现以上目标? 问题答案:

  • 问题内容: 有什么方法可以创建线程以一次运行多个方法吗? 这样,如果任何方法在所有其他线程之间失败,则应终止。 问题答案: 每个node.js进程在设计上都是单线程的。因此,要获得多个线程,您必须具有多个进程(正如其他一些发帖人所指出的那样,您还可以链接到一些库,这些库使您能够使用Node中的线程,但是没有这些库就没有这种能力。请参阅Shawn Vincent的回答,参考https://githu

  • 问题内容: 传统观点告诉我们,大量的企业Java应用程序应优先使用线程池,而不是产生新的工作线程。使用使得这很简单。 但是,确实存在线程池不太适合的情况。我当前正在使用的具体示例是使用,它允许将变量“传递”给任何产生的线程。使用线程池时,此机制会中断,因为辅助线程通常不是从请求线程派生的,而是预先存在的。 现在有解决方法(可以将线程局部变量显式传入),但这并不总是适当或实际的。最简单的解决方案是按

  • 问题内容: 抱歉,这个问题很愚蠢。我试图在网上找到答案已有一段时间,但找不到,因此我在这里提问。我正在学习线程,并且一直在浏览此链接以及有关内核级和用户级线程的2013年Linux Plumbers Conference 2013视频 ,据我了解,使用pthreads在用户空间中创建线程,而内核并不知道关于此问题,并且仅将其视为单个进程,而不知道内部有多少个线程。在这种情况下, 内核在将进程视为时