In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-03-26 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/03 Report--
This article mainly explains the "Thread.start () thread start method is what", the article explains the content is simple and clear, easy to learn and understand, the following please follow the editor's train of thought slowly in depth, together to study and learn "Thread.start () let thread start method is what" it!
Thread startup analysis
New Thread (()-> {/ / todo}) .start ()
"ahem", Java thread creation and startup is very simple, but if you ask how a thread is started, it is often not clear, or even why it is started with a call to start () instead of the run () method?
"then", in order to give you a more intuitive understanding, let's stand from the perspective of God. The thread code of this Java, to the use of the JDK method, and the corresponding processing process of JVM, are shown to you to facilitate our subsequent step-by-step analysis.
Figure 19-1 Thread startup analysis
The "above", which is the overall process analysis of a thread startup, will involve the following knowledge points:
The startup of the thread involves a call to the local method (JNI), which is the part of the code written by C++.
In the implementation of JVM, there will be unified processing of threads by different operating systems, such as Win, Linux, Unix.
Thread startup involves the thread's life cycle state (RUNNABLE), as well as the wake-up operation, so there will eventually be a callback operation. That is to call our run () method
Next, we begin to analyze the execution of each step of the source code step by step to understand the thread startup process.
Thread startup process
1. Thread start UML diagram
Figure 19-2 Thread start UML diagram
As shown in figure 19-2, the sequence diagram of the thread startup process, the overall link is long, will involve the operation of JVM. The core source code is as follows:
Thread.c: https://github.com/unofficial-openjdk/openjdk/blob/jdk/jdk/src/java.base/share/native/libjava/Thread.c
Jvm.cpp: https://github.com/JetBrains/jdk8u_hotspot/blob/master/src/share/vm/prims/jvm.cpp
Thread.cpp: https://github.com/JetBrains/jdk8u_hotspot/blob/master/src/share/vm/runtime/thread.cpp
Os.cpp: https://github.com/JetBrains/jdk8u_hotspot/blob/master/src/share/vm/runtime/os.hpp
Os_linux.cpp: https://github.com/JetBrains/jdk8u_hotspot/blob/master/src/os/linux/vm/os_linux.cpp
Os_windows.cpp: https://github.com/JetBrains/jdk8u_hotspot/blob/master/src/os/windows/vm/os_windows.cpp
VmSymbols.hpp: https://github.com/JetBrains/jdk8u_hotspot/blob/master/src/share/vm/classfile/vmSymbols.hpp
2. Start Thread at Java level
2.1 start () method
New Thread (()-> {/ / todo}) .start (); / / JDK source code public synchronized void start () {if (threadStatus! = 0) throw new IllegalThreadStateException (); group.add (this); boolean started = false; try {start0 (); started = true } finally {try {if (! started) {group.threadStartFailed (this);}} catch (Throwable ignore) {}
The thread startup method start () has described the core content in its method English comments. Causes this thread to begin execution; the Java Virtual Machine calls the run method of this thread. This means that the run method of this thread is called by JVM so that the thread starts execution. In fact, this is a JVM callback process, which will be discussed in the following source code analysis.
In addition, start () is a synchronized method, but in order to avoid multiple calls, it is judged by the thread state in the method. ThreadStatus! = 0.
Group.add (this), which adds the current thread to the thread group, ThreadGroup.
Start0 (), which is a local method, is called and executed by JNI. The operation of this step is the core step of starting the thread.
2.2 start0 () local method
/ / Local method start0 private native void start0 (); / / register local method public class Thread implements Runnable {/ * Make sure registerNatives is the first thing does. * / private static native void registerNatives (); static {registerNatives ();} / /.}
Start0 (), which is a local method that starts the thread.
RegisterNatives (), which is used to register some local methods needed during thread execution, such as start0, isAlive, yield, sleep, interrupt0, and so on.
"registerNatives". The local method is defined in Thread.c. The following is the core source code of the definition:
Static JNINativeMethod methods [] = {{"start0", "() V", (void *) & JVM_StartThread}, {"stop0", "(" OBJ ") V", (void *) & JVM_StopThread}, {"isAlive", "() Z", (void *) & JVM_IsThreadAlive}, {"suspend0", "() V" (void *) & JVM_SuspendThread}, {"resume0", "() V", (void *) & JVM_ResumeThread}, {"setPriority0", "(I) V", (void *) & JVM_SetThreadPriority}, {"yield", "() V", (void *) & JVM_Yield}, {"sleep" "(J) V", (void *) & JVM_Sleep}, {"currentThread", "()" THD, (void *) & JVM_CurrentThread}, {"interrupt0", "() V", (void *) & JVM_Interrupt}, {"holdsLock", "(" OBJ ") Z", (void *) & JVM_HoldsLock}, {"getThreads" "() [" THD, (void *) & JVM_GetAllThreads}, {"dumpThreads", "[" THD ") [[" STE, (void *) & JVM_DumpThreads}, {"setNativeName", "(" STR ") V", (void *) & JVM_SetNativeThreadName},}
"Source Code": https://github.com/unofficial-openjdk/openjdk/blob/jdk/jdk/src/java.base/share/native/libjava/Thread.c
As you can see from the definition, the start0 method executes the & JVM_StartThread method, which eventually starts the thread at the JVM level.
3. JVM create thread
3.1 JVM_StartThread
"Source Code": https://github.com/JetBrains/jdk8u_hotspot/blob/master/src/share/vm/prims/jvm.cpp
JVM_ENTRY (void, JVM_StartThread (JNIEnv* env, jobject jthread) JVMWrapper ("JVM_StartThread"); JavaThread * native_thread = NULL; / / create thread native_thread = new JavaThread (& thread_entry, sz); / / start thread Thread::start (native_thread); JVM_END
There is a lot of code in this part, but the core content is mainly to create and start threads. In addition, & thread_entry is also a method, as follows:
"thread_entry, thread entry"
Static void thread_entry (JavaThread* thread, TRAPS) {HandleMark hm (THREAD); Handle obj (THREAD, thread- > threadObj ()); JavaValue result (T_VOID) JavaCalls::call_virtual (& result, obj, KlassHandle (THREAD, SystemDictionary::Thread_klass (), vmSymbols::run_method_name (), vmSymbols::void_method_signature (), THREAD);}
"important", when creating a method for a thread to introduce this thread entry, the thread_entry includes Java's callback function JavaCalls::call_virtual. This callback function is called by JVM.
"vmSymbols::run_method_name ()" is the callback method. The source code is as follows:
"Source Code": https://github.com/JetBrains/jdk8u_hotspot/blob/master/src/share/vm/classfile/vmSymbols.hpp
# define VM_SYMBOLS_DO (template, do_alias) template (run_method_name, "run")
This run is the run method that will be called in our Java program. Next, we continue to execute the link according to the code to find out when the callback method was called.
3.2 JavaThread
Native_thread = new JavaThread (& thread_entry, sz)
Next, let's move on to the source code execution of JavaThread.
"Source Code": https://github.com/JetBrains/jdk8u_hotspot/blob/master/src/share/vm/runtime/thread.cpp
JavaThread::JavaThread (ThreadFunction entry_point, size_t stack_sz): Thread () # if INCLUDE_ALL_GCS, _ satb_mark_queue (& _ satb_mark_queue_set), _ dirty_card_queue (& _ dirty_card_queue_set) # endif / / INCLUDE_ALL_GCS {if (TraceThreadEvents) {tty- > print_cr ("creating thread% p", this);} initialize () _ jni_attach_state = _ not_attaching_via_jni; set_entry_point (entry_point); / / Create the native thread itself. / /% note runtime_23 os::ThreadType thr_type = os::java_thread; thr_type = entry_point = & compiler_thread_entry? Os::compiler_thread: os::java_thread; os::create_thread (this, thr_type, stack_sz);}
ThreadFunction entry_point is the thread_entry method above.
Size_t stack_sz, which represents the number of threads already in the process.
Both parameters are passed to the os::create_thread method, which is used by the creation thread.
3.3 os::create_thread
Source code:
Os_linux.cpp: https://github.com/JetBrains/jdk8u_hotspot/blob/master/src/os/linux/vm/os_linux.cpp
Os_windows.cpp: https://github.com/JetBrains/jdk8u_hotspot/blob/master/src/os/windows/vm/os_windows.cpp
As we all know, JVM is what!, so its OS service implementation, Liunx, Windows and so on, will implement the thread creation logic. It's kind of like the adapter pattern.
"os_linux-> os::create_thread"
Bool os::create_thread (Thread* thread, ThreadType thr_type, size_t stack_size) {assert (thread- > osthread () = = NULL, "caller responsible"); / / Allocate the OSThread object OSThread* osthread = new OSThread (NULL, NULL); / / Initial state is ALLOCATED but not INITIALIZED osthread- > set_state (ALLOCATED); pthread_t tid; int ret = pthread_create (& tid, & attr, (void* (*) (void*)) java_start, thread) Return true;}
Osthread- > set_state (ALLOCATED) to initialize the assigned state, but not at this time.
Pthread_create is a function that creates threads similar to Unix operating systems (Unix, Linux, Mac OS X, etc.).
Java_start, which focuses on classes, is the way to actually create threads.
3.4 java_start
"Source Code": https://github.com/JetBrains/jdk8u_hotspot/blob/master/src/os/linux/vm/os_linux.cpp
Static void * java_start (Thread * thread) {/ / Thread ID int pid = os::current_process_id (); / / set thread ThreadLocalStorage::set_thread (thread); / / set thread status: INITIALIZED initialization completion osthread- > set_state (INITIALIZED); / / Wake up all threads sync- > notify_all () / / loop, initialize the state, then consistently wait for wait while (osthread- > get_state () = = INITIALIZED) {sync- > wait (Mutex::_no_safepoint_check_flag);} / / after waking up, execute the run method thread- > run (); return 0;}
JVM sets thread state, and INITIALIZED initialization is complete.
Sync- > notify_all () to wake up all threads.
Osthread- > get_state () = = INITIALIZED,while loop waiting
Thread- > run (), which waits for the thread to wake up, that is, after the state changes. This is also reflected in our thread execution UML diagram.
4. JVM starts the thread
JVM_ENTRY (void, JVM_StartThread (JNIEnv* env, jobject jthread) JVMWrapper ("JVM_StartThread"); JavaThread * native_thread = NULL; / / create thread native_thread = new JavaThread (& thread_entry, sz); / / start thread Thread::start (native_thread); JVM_END
There are two steps in JVM_StartThread, creating (new JavaThread) and starting (Thread::start). The process of creation is over, and then we talk about starting.
4.1 Thread::start
"Source Code": https://github.com/JetBrains/jdk8u_hotspot/blob/master/src/share/vm/runtime/thread.cpp
Void Thread::start (Thread* thread) {trace ("start", thread); if (! DisableStartThread) {if (thread- > is_Java_thread ()) {java_lang_Thread::set_thread_status (JavaThread*) thread)-> threadObj (), java_lang_Thread::RUNNABLE) } / / different OS has different startup code logic os::start_thread (thread);}}
If thread DisableStartThread is not disabled and it is Java thread thread- > is_Java_thread (), set the thread state to RUNNABLE.
Os::start_thread (thread), which calls the thread startup method. Different OS will have different startup code logic
4.2 os::start_thread (thread)
"Source Code": https://github.com/JetBrains/jdk8u_hotspot/blob/master/src/share/vm/runtime/os.hpp
Void os::start_thread (Thread* thread) {/ / guard suspend/resume MutexLockerEx ml (thread- > SR_lock (), Mutex::_no_safepoint_check_flag); OSThread* osthread = thread- > osthread (); osthread- > set_state (RUNNABLE); pd_start_thread (thread);}
Osthread- > set_state (RUNNABLE), set the thread state RUNNABLEpd_start_thread (thread), and start the thread, which is implemented by each OS implementation class to implement the startup method of their respective system. For example, the code for the windows system and the Linux system is completely different.
4.3 pd_start_thread (thread)
"Source Code": https://github.com/JetBrains/jdk8u_hotspot/blob/master/src/os/linux/vm/os_linux.cpp
Void os::pd_start_thread (Thread* thread) {OSThread * osthread = thread- > osthread (); assert (osthread- > get_state ()! = INITIALIZED, "just checking"); Monitor* sync_with_child = osthread- > startThread_lock (); MutexLockerEx ml (sync_with_child, Mutex::_no_safepoint_check_flag); sync_with_child- > notify ();}
This part of the code notify () is the most critical, which wakes up the thread.
After the thread wakes up, thread- > run (); in 3. 4 is ready to proceed.
5. JVM thread callback
5.1 thread- > run () [JavaThread::run ()]
"Source Code": https://github.com/JetBrains/jdk8u_hotspot/blob/master/src/share/vm/runtime/thread.cpp
/ / The first routine called by a new Java thread void JavaThread::run () {/ /... Initialize thread operation thread_main_inner ();}
The thread- > run () in the java_start in the os_linux.cpp class ends up calling thread.cpp 's JavaThread::run () method.
This section needs to move on, thread_main_inner (); method.
5.2 thread_main_inner
"Source Code": https://github.com/JetBrains/jdk8u_hotspot/blob/master/src/share/vm/runtime/thread.cpp
Void JavaThread::thread_main_inner () {if (! this- > has_pending_exception () & &! java_lang_Thread::is_stillborn (this- > threadObj ()) {{ResourceMark rm (this); this- > set_native_thread_name (this- > get_thread_name ());} HandleMark hm (this); this- > entry_point () (this, this) } DTRACE_THREAD_PROBE (stop, this); this- > exit (false); delete this;}
Here is the thread name of the settings you are familiar with, this- > set_native_thread_name (this- > get_thread_name ()).
This- > entry_point (), the thread_entry method in 3. 1 is actually called.
Thread_entry, the method will eventually be called to vmSymbols::run_method_name () in JavaCalls::call_virtual. This is the run () method, at which point the thread starts and finishes. Finally, it's back!
Summary
The thread startup process involves the involvement of JVM, so it's really hard to understand it so thoroughly from a local method without careful understanding.
The whole source code analysis can be combined with the code call UML sequence diagram to learn, the basic core process includes: Java creation thread and startup, calling the local method start0 (), JVM_StartThread creation and startup in JVM, setting thread state waiting to be awakened, starting thread and waking up according to different OS, and finally calling back run () method to start Java thread.
Sometimes it may be a very simple method, and it will also have its depth. When you really understand it, you don't have to memorize it. If you need to get the above high-definition large image, you can add small Fu GE Wechat (fustack). Note: Thread large image.
Thank you for reading, the above is the content of "what is the method of Thread.start () to start threads". After the study of this article, I believe you have a deeper understanding of what is the method of Thread.start () to let threads start, and the specific use needs to be verified in practice. Here is, the editor will push for you more related knowledge points of the article, welcome to follow!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.