Java multithreading summary (1)

Introduction to Multithreading

Before introducing multithreading, you should first understand the concepts of threads and processes.

  • Processes
    Processes are programs that are running and the system resources that programs need to run . To be precise, when a program enters the memory to run, it becomes a process and has certain independent functions (independence here means that the system resources occupied by different processes are relatively independent).
  • Thread A
    thread is a unit of execution in a process, and there is at least one thread in a process. Threads claim to not be able to run automatically, but must reside in a process and be triggered and executed by the process. All threads belonging to the same process share the system resources of that process.

Microscopically, in a single-CPU computer, only one thread can be executed at a time. Implementing multithreading is to make multiple threads execute at the same time on a macro level. The CPU uses the preemptive scheduling mode to perform high-speed switching among multiple threads , which can improve the utilization rate of system resources, especially the CPU, and improve the execution efficiency of the entire program. Let's illustrate with an example from life

One store had 10 people queuing to check out, the line was lined up, and there was only one cashier at the counter. During the period of time when the customer pays for the payment, the cashier is in an idle state, and can only wait for the next person after the payment is successful. If the line is in two lines, when a customer pays in one line, the cashier can turn to the other line to count the goods, and keep switching between the two sides, which can speed up the speed of the entire line. The two queues can be regarded as two threads, and the cashier can be regarded as the CPU.

multi-threaded implementation

class Person{
    Stirng name;
    public Person(String name){
        this.name = name;
    }
    void show(){
        for(int i = 1; i<=100, i++){
            System.out.println("name="+name+",i="+i);
        }
    }
}
class ThreadDemo{
    public static void main(String[] args){
        Person p1 = new Person("张三"); //主线程开始
        Person p2 = new Person("李四");
        p1.show();
        p2.show(); //主线程结束
    }
}

When the program is executed, the Java virtual machine finds the mainmethod and starts to execute until the mainmethod is executed. This path is called the main thread of Java . In the above code, the main thread needs to execute the show()method , for a total of 200 loops. At this time, the execution efficiency of the program is obviously very low. So how to use multi-threading to solve this problem?

create thread

There are two ways to create a thread and a new thread

1. Inherit the Thread class to create a thread

step:

  • Define a class that inherits Thread and override the run()methods in Thread
  • Create a subclass object (i.e. create a new thread)
  • call start()method

Code demo:

/*
*自定义线程
*/
class MyThread extends Thread{
    @Override
    public void run(){
        for(int i = 1; i<=200; i++){
            System.out.println("自定义线程"+i);
        }
    }
}
public class Test{
    public static void main(String[] args){
        MyThread p = new MyThread(); 
        //获取开始时间
        long startTime = System.currentTimeMillis();    
        p.start();
        for(int i = 1; i<=200; i++){
            System.out.println("主线程"+i);
        }
        //获取结束时间
        long endTime = System.currentTimeMillis();
        System.out.println("程序运行时间:" + (endTime - startTime) + "ms");
    }
}

The above code implements multi-threading. The following is a few explanations of the specific implementation principle:

① The content to be executed is in the run()method , why not call run()the method, but call the start()method ?

The reference calling run()method just an ordinary method call , and will not open a new thread; and calling the start()method will open a new thread.

The general process is: call the start()method to open a new thread -> call run()the method by the Java virtual machine -> the virtual machine puts the run()method into the new thread -> finally, the CPU autonomously chooses which thread to execute each time

② Why inherit Threadclasses ? Override run()method ?

The main thread mentioned earlier, the tasks it wants to perform are defined in a class main()method . The tasks to be performed by the custom thread are defined in the run()method , and the tasks in Threadthe run()method not what we need, so we have to write a class to inherit from the Threadclass and override its run()method

③ The following is the memory diagram of the multi-threaded example

Multithreaded memory diagram
When a multithreaded program is executed, each execution thread has its own stack memory space (that is, the stack memory is private to the thread). In the figure, when the execution arrives p.start(), a new thread is opened, a new space is opened in the stack memory, and the rewritten run()method is called, and the stack (new thread stack area) is executed.

2. Implement the Runnableinterface to create a thread

Another way to create a thread is to define a class that implements Runnablean interface .

step:

  • Define the class to implement the Runnableinterface and override the run()methods in the interface
  • Create an object Threadof class
  • Pass the subclass object of the interface as a parameter to the Threadclass constructor
  • ThreadCall the start()method of the class to start the thread

Code demo:

/*
*自定义线程
*/
public class MyRunnable implements Runnable{
    @Override
    public void run(){
        for(int i=0; i<10; i++){
            System.out.println("自定义线程:"+i);
        }
    }
}
class test{
    public static void main(Stirng[] args){
        Runnable run = new MyRunnable();
        Thread t = new Thread(run);
        t.start();
        for (int i = 0; i < 10; i++) {
            System.out.println("main"+i);
        }
    } 
}

So what is the difference between inheriting Threada class and implementing Runnablean interface?

Implementing interfaces to avoid the single inheritance limitations of inheritance

ThreadA thread can only be started when an object of the class is created . Thread tasks are defined in Runnablethe overridden run() method of the interface implementation class. Since the Runnableinterface does not have the function of opening threads, only the implementation class object is passed as a parameter Threadto the constructor of the class. This way, when creating a thread object, it is clear what task to perform.

The method of inheriting Threadclass couples thread objects and thread tasks together, which is not conducive to program design. Implementing an interface is more in line with object-oriented thinking. Threads are divided into two parts: one part is the thread object; the other part is the thread task (that is, the code in the run()method ), which achieves a large degree of decoupling.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324769511&siteId=291194637