In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-03-27 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
This article is about how to start the Java thread. The editor thinks it is very practical, so share it with you as a reference and follow the editor to have a look.
First, 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 called start () instead of the run () method?
So, 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.
The above is the overall process analysis of a thread startup, which 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.
Second, thread startup process
1. Thread start UML diagram
This is the sequence diagram of the thread startup process, and the overall link is long, which will involve the operation of JVM. The core source code is as follows:
Thread.c
Jvm.cpp
Thread.cpp
Os.cpp
Os_linux.cpp
Os_windows.cpp
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 start0private 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},}
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
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);}
Importantly, when creating a method for a thread to introduce this thread entry, 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:
# 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.
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 of these parameters are passed to the os::create_thread method for use by the creation thread.
3.3 os::create_thread
Source code:
Os_linux.cpp:
Os_windows.cpp:
As we all know, what a JVM is! So its OS service implementation, Liunx, Windows, etc., all implement thread creation logic. It's kind of like the adapter pattern.
Os_linux-> os::create_threadbool 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
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
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)
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 thread status RUNNABLE
Pd_start_thread (thread), the startup thread, which is implemented by each OS implementation class to implement the startup methods of their respective systems. For example, the code for the windows system and the Linux system is completely different.
4.3 pd_start_thread (thread)
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 ()]
/ / The first routine called by a new Java threadvoid 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
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!
Thank you for reading! This is the end of this article on "how to start Java threads". I hope the above content can be of some help to you, so that you can learn more knowledge. if you think the article is good, you can share it out for more people to see!
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: 217
*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.