The order of execution threads - high concurrency of

First, the order of execution threads is uncertain

Call Thread's start () method when starting a thread, a thread of execution order is uncertain. In other words, in the same method, after continuous create multiple threads, the thread calls the start () method of the order does not determine the order of execution threads.

For example, here, consider a simple example, as shown below.

package io.binghe.concurrent.lab03;

/**
 * @author binghe
 * @version 1.0.0
 * @description 线程的顺序,直接调用Thread.start()方法执行不能确保线程的执行顺序
 */
public class ThreadSort01 {
    public static void main(String[] args){
        Thread thread1 = new Thread(() -> {
            System.out.println("thread1");
        });
        Thread thread2 = new Thread(() -> {
            System.out.println("thread2");
        });
        Thread thread3 = new Thread(() -> {
            System.out.println("thread3");
        });

        thread1.start();
        thread2.start();
        thread3.start();
    }
}

In ThreadSort01 class we were created three different threads, thread1, thread2 and thread3, next in the program in order to call thread1.start () respectively, thread2.start () and thread3.start () method to start respectively three different threads.

So, the question is, whether the order of execution threads execute it in the order thread1, thread2 and thread3 of? The method of operation of the main ThreadSort01 results shown below.

thread1
thread2
thread3

Running again, the results shown below.

thread1
thread3
thread2

The third run, the results shown below.

thread2
thread3
thread1

It can be seen every time the program is run, the order of execution threads may be different. Thread startup sequence does not determine the order of execution threads.

Second, how to ensure the implementation of order thread

1. Ensure that a simple example of thread execution order

In the real business scenarios, sometimes, after starting the thread you may need to rely first start threads execute business logic to complete the proper execution thread. At this point, it is necessary to ensure that the order of execution threads. So how do you ensure that the order of execution threads it?

You can join () method of the Thread class to ensure the order of execution threads. For example, the following test code.

package io.binghe.concurrent.lab03;

/**
 * @author binghe
 * @version 1.0.0
 * @description 线程的顺序,Thread.join()方法能够确保线程的执行顺序
 */
public class ThreadSort02 {
    public static void main(String[] args) throws InterruptedException {

        Thread thread1 = new Thread(() -> {
            System.out.println("thread1");
        });
        Thread thread2 = new Thread(() -> {
            System.out.println("thread2");
        });
        Thread thread3 = new Thread(() -> {
            System.out.println("thread3");
        });

        thread1.start();

        //实际上让主线程等待子线程执行完成
        thread1.join();

        thread2.start();
        thread2.join();

        thread3.start();
        thread3.join();
    }
}

We can see, ThreadSort02 analogy ThreadSort01 classes, each thread start method add the following call to join the thread () method. In this case, operation ThreadSort02 class results are shown below.

thread1
thread2
thread3

Running again, the results shown below.

thread1
thread2
thread3

The third run, the results shown below.

thread1
thread2
thread3

You can see, the results of each run are the same, so the use of Thread join () method to ensure that the thread has executed the order.

How 2.join way to ensure the order of execution threads

Since the Thread class's join () method to ensure that the order of execution threads, we take a look at join Thread class () method in the end is what ghost.

Thread enter the join () method, as shown below.

public final void join() throws InterruptedException {
    join(0);
}

See join () method call in a similar reference join () method, passing the parameter 0. To follow up the code, as follows.

public final synchronized void join(long millis)
throws InterruptedException {
	long base = System.currentTimeMillis();
	long now = 0;

	if (millis < 0) {
		throw new IllegalArgumentException("timeout value is negative");
	}

	if (millis == 0) {
		while (isAlive()) {
			wait(0);
		}
	} else {
		while (isAlive()) {
			long delay = millis - now;
			if (delay <= 0) {
				break;
			}
			wait(delay);
			now = System.currentTimeMillis() - base;
		}
	}
}

You can see, there is a long join type parameter () method uses synchroinzed modified, indicating that this method can only be one instance at a time or method call. Because, parameter passing to 0, the program will enter the following code logic.

if (millis == 0) {
	while (isAlive()) {
		wait(0);
	}
}

First, the code way while loop to determine whether the current thread has been started in the active state, if already started in the active state, wait () method is invoked its kind, and pass parameters 0. Follow up () method, as shown wait.

public final native void wait(long timeout) throws InterruptedException;

You can see, wait () method is a local method, by calling the underlying JDK JNI ways and means to make the thread wait for execution to complete.

Note that, when the calling thread wait () method, will make the main thread in a wait state, waiting for the child thread executed after completion of execution down again. That execution, in the main ThreadSort02 class () method, call the child thread join () method will block main () method, when the child thread execution is completed, main () method will continue down, start the second sub-threads, and executes the business logic sub-thread, and so on.

 

Released 1303 original articles · won praise 2000 · Views 5.13 million +

Guess you like

Origin blog.csdn.net/l1028386804/article/details/104344841