How does Java start threads? What does Java do when it calls thread.start ()? What is the relationship between threads in Java and threads in the operating system?

Linux Start thread

First, let’s take a look at how Linux starts a thread. The knowledge involved here is quite complex, but I’ll just outline the process. The following code is the underlying Linux source code provided by the Glibc library through the pthread_create() method, which is used to create a thread.

int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
            void *(*start_routine) (void *), void *arg);
Copy the code

If you have a LINXU system you can input:man 3 pthread_createTo query the function of this method, as shown in the following figure: Descriptioncreate a new threadCreate a thread



Pthread_create creates a thread, which is a Linux function that can be called directly from C or C++. Let’s take a look at the four arguments in this method

Parameter name Parameters are defined Parameter interpretation
pthread_t  *thread The id of the created thread is passed out after the call Define pthread_t PID and then take the address & PID
const pthread_attr_t  *attr Thread properties, about thread properties is Linux knowledge Usually null is passed and the default properties remain
void (start_routine) (void *) The body function of the thread after it is started You need to define a function and pass the name of the function
void *arg Arguments to the body function None can be passed null

From the above explanation, we can derive a test code for the Linux startup thread

/ / header files
#include <pthread.h>
#include <stdio.h> 
// Define a variable that accepts the id of the created thread pthread_t pid;
// Define the thread's body function
void* thread_entity(void* arg) {
    printf("i am new Thread! from c");
}
// The main method is the entry to the program. Main, like Java's main, produces a process, which in turn produces a main thread
int main(a) {
	// Call the operating system function to create the thread. Note the four arguments
	pthread_create(&pid,NULL,thread_entity,NULL); 
    // "sleep" means "sleep" and "sleep" means "sleep".
    // Why do you need sleep? What happens if you don't sleep
    usleep(100);
    printf("main\n");
	return 0; 
}
Copy the code

Java startup thread

Java start thread code is as follows:

        Thread thread = new Thread(new Runnable() {
            @Override
            public void run(a) {
                System.out.println("java thread"); }});// Call the start method --> run method
        //private native void start0();
        thread.start();
Copy the code

Private native void start0(); private native void start0(); Method, the start0 method calls the JVM’s underlying methods (Hotspot source code), which in turn creates a thread by calling the pthread_create method in the system OS layer’s xxx.c file. To further demonstrate, we can simulate Java code calling the.c code directly through JNI, and then the.c implementation calls the Linux function pthread_create to create a thread.

#include <pthread.h>
#include <stdio.h> // Define the variable to accept the thread ID
pthread_t pid; 
We're not going to go into how the JVM calls the Run method in Java, because it's all at the C/C++ level. What we need to know is that the thread created by Linux executes the run method in Java, right
void* thread_entity(void* arg) {
// The child thread loops indefinitely
    while(1) {// Sleep for 100 milliseconds
	usleep(100);
	/ / print
	printf("I am new Thread\n"); }}// The c language main method entry method, equivalent to Java main
int main(a) {
	// Create a thread by calling a Linux system function
    pthread_create(&pid,NULL,thread_entity,NULL); // The main thread is an infinite loop
	while(1) {// Sleep for 100 milliseconds
        usleep(100);
	/ / print
	printf("I am main\n");
	}
	return 0;
}
Copy the code

Let’s test whether the above C program can be run in Linux by executing the following command:

gcc thread.c - thread.out -pthread

Run the program:./thread.out





Simulate a Java thread and call the start1 local method to start a system thread inside the local method.

public class ZLThread {
    static {
        System.loadLibrary("EnjoyThreadNative");
    }

    public native void start1(a);

    public static void main(String[] args) {
        ZLThread zlThread = newZLThread(); zlThread.start1(); }}Copy the code

Java -h xx. Java to compile a header file. Then copy the methods in the header file to the.c file mentioned above. The method needs to be set up correctly and compiled to a SO file

#include <pthread.h>
#include <stdio.h> // Define the variable to accept the thread ID
pthread_t pid; // The thread's principal method is the Java equivalent of run
void* thread_entity(void* arg) {
// The child thread loops indefinitely
    while(1) {// Sleep for 100 milliseconds
	usleep(100);
	/ / print
	printf("I am new Thread\n"); }}// Open the.h file and copy the method name to it
// The parameter is fixed
Java_com_shadow_app_EnjoyThread_start0(JNIEnv *env, jobject c1) {
// Create a thread by calling a Linux system function
    pthread_create(&pid,NULL,thread_entity,NULL); // The main thread is an infinite loop
	while(1) {// Sleep for 100 milliseconds
        usleep(100);
	/ / print
	printf("I am main\n"); }}Copy the code

Command to compile so file: gcc -fPIC -I /home/shadows/soft/jdk11/include -I /home/shadows/soft/jdk11/include/linux -shared -o libxxx.so Threadnew. c Make sure that the name of the generated SO file corresponds to that in the Java program

static { // If you are libxxx; I'll just write XXX here
      System.loadLibrary( "xxx" );
   }
Copy the code

Then add the so file directory to the system variable, Otherwise, Java is can’t find so file export LD_LIBRARY_PATH = $LD_LIBRARY_PATH: / home/we/tools/enjoy/com/shadow/app/and then through the Java command to run the Java file, You can see that Java created the thread. In this case, a Java call to thread.start () is a JVM call to a low-level method at the OS layer to create a Thread. This is why when the start method is called, the Java thread state will go into the ready state and will not be started immediately, because the CPU creates the thread through the OS, and after the thread is created, Java’s run method is called through JNI. OK, so that proves the three questions at the beginning of the article:

  • Java calls the OS system creation thread through the JVM
  • Thread.start() –> Navtive start0 –> JVM –> thread.c: Start0 () –> JVM instantiates a C++ object JavaThread –> OS pthread_create() creates the Thread –> Thread is created –> JVM –> thread.run () method
  • Threads at the Java level are threads at the operating system level


The following is summarized through a flowchart:



Supplementary Remarks (supplementary only)

The man command is a help command in Linux. You can use the man command to view the command help, configuration file help, and programming help in Linux.

grammar

Man (option)(parameter)Copy the code

options

-a: Search in all man help manuals. -f: is equivalent to the whatis directive, which displays a short description of the given keyword; -p: Use a pager when specifying content. -m: specifies the search path for man manuals.Copy the code

parameter

  • Numbers: Specifies which man manual to search for help from;
  • Keyword: Specifies the keyword for searching for help.

Numbers represent content

1: commands or execution files that can be operated by users in shell environment; /dev = /dev; /dev = /dev; /dev = /dev; /dev = /dev; /dev = /dev; /dev = /dev; /dev = /dev; Conventions and protocols, such as Linux file system, network protocol, ASCII Code, etc. 8: management commands available to system administrators 9: files related to the kernelCopy the code

The instance

If we type man ls, it will display “ls (1)” in the upper-left corner. In this case, “ls” means the manual name and “(1)” means that the manual is in the first chapter. Similarly, if we type man ifconfig, it will display “ifconfig (8)” in the upper-left corner. You can also enter the command “man [section number] Manual name”. Man is searched in the order of the chapter number in the manual, for example:

man sleep
Copy the code

Only the manual for the sleep command is displayed. To view the library function sleep, type:

man 3 sleep
Copy the code