Start multithreading correctly on the basis of concurrency

Keywords: Java

Comparison between start method and run method

Many people, including myself, also thought that both run and start methods can start a thread, and both functions are similar. Then they realized that this was wrong in the process of learning, and they are different from each other. Let's start with a demo code:

/**
 * @author Chen
 * @Description start()Compare with run() method
 * @create 2019-11-05 22:01
 */
public class StartAndRunMethod {
    public static void main(String[] args) {
        //Using the run method
        Runnable runnable = ()-> System.out.println(Thread.currentThread().getName());
        runnable.run();

        //Using the start method
        new Thread(runnable).start();
    }
}

Output results:

main
Thread-0

As you can see, the thread executing the run method is the main thread, while the thread executing the start method is a new sub thread.

Interpretation of start method

We all know that the start method is to start a new thread. In fact, there are two threads involved in the execution of the start method, one is the main thread, the other is a new sub thread. When the start method is called, the sub thread will not start up immediately. The sub thread will obtain some resources other than the CPU, enter the state, and wait for the CPU to call. As for when to call, this is not what we can decide, but what the thread scheduler decides. So some threads that run the start method first may start slower than the thread that calls the start method later.

What happens when we call the start method twice?

An illegal thread state exception will be thrown. In fact, once the thread is executed, it will enter the runnable state. Once the execution is completed, it will enter the end state and will not return.

Next, let's take a closer look at start() to see what it did during its execution.

  public synchronized void start() {
        /**
         * This method is not invoked for the main method thread or "system"
         * group threads created/set up by the VM. Any new functionality added
         * to this method in the future may have to also be added to the VM.
         *
         * A zero status value corresponds to state "NEW".
         */
        if (threadStatus != 0)
            throw new IllegalThreadStateException();

        /* Notify the group that this thread is about to be started
         * so that it can be added to the group's list of threads
         * and the group's unstarted count can be decremented. */
        group.add(this);

        boolean started = false;
        try {
            start0();
            started = true;
        } finally {
            try {
                if (!started) {
                    group.threadStartFailed(this);
                }
            } catch (Throwable ignore) {
                /* do nothing. If start0 threw a Throwable then
                  it will be passed up the call stack */
            }
        }
    }

In start(), the status of the thread will be checked first to determine whether the threadStatus is equal to 0, that is, whether it is a newly started thread. This is the reason why start() throws an exception twice. (the default state is 0 when the online program is just initialized)

Then I did the act of joining the thread group, and then I executed a native method of start0.

Interpretation of run method

In fact, the run method is relatively simple, with only three lines of code: if the target, that is, the incoming interface, is not empty, the content of the rewritten run method will be executed; otherwise, the content of the incoming run method will be executed.

    @Override
    public void run() {
        if (target != null) {
            target.run();
        }
    }

So when we execute the run method, it will be used as a common method, as we write it ourselves, so the console prints out a main thread.

So if we want to start a new thread, we should not call the run method directly, but should call the start method to call the run method indirectly.

Posted by hnxuying on Tue, 05 Nov 2019 10:36:41 -0800