1. Thread. join ()
If you call the join () function of another thread in a process such as main, the main function will be blocked until the thread is executed.
public class JoinTest {public static void main(String[] args) {System.out.println("main starts.");Thread thread = new Thread(new Runnable() {public void run() {for(int i = 0;i < 5;i++){try {System.out.println("thread" + i + " starts.");Thread.sleep(500);} catch (InterruptedException e) {e.printStackTrace();}}}});thread.start();try {thread.join();} catch (InterruptedException e) {e.printStackTrace();}System.out.println("main ends.");}}
Output result:
main starts.thread0 starts.thread1 starts.thread2 starts.thread3 starts.thread4 starts.main ends.
From the output result, the main thread prints the main starts and runs it to the thread. the join () is blocked. At this time, the sub-thread starts to print logs and the printing interval is 500 ms. After the sub-thread completes execution, the main thread prints the output main ends.
If we change thread. join () to thread. join (1500), the output is as follows:
main starts.thread0 starts.thread1 starts.thread2 starts.main ends.thread3 starts.thread4 starts.
Join (long millis) is an overload method of join. It means that the thread that calls this function can continue to execute after the thread is executed or the millis time is blocked. From the above output, we can see that the main thread does not wait for the thread to complete the execution, but waits for MS to continue the execution.
In fact, this method can also be used to implement the main thread waiting for the thread:
//try {//thread.join();//} catch (InterruptedException e) {//e.printStackTrace();//}while(thread.isAlive()){try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}}
Determine whether the thread is in the alive status. If yes, the main thread sleep for 100 ms. If the thread ends, the main thread continues to run.
2. CountDownLatch
CountDownLatch maintains a counter. during initialization, it accepts an integer value as the counter's initial value, including two functions await and countDown. When await is called in a function, the thread is blocked, the countDown counter value is not called once minus one. Only when the counter value is 0 Can the blocked thread continue to execute downward.
Public class CountDownLatchTest {public static void main (String [] args) throws returns {final CountDownLatch startCdt = new CountDownLatch (5); final CountDownLatch endCdt = new CountDownLatch (5 ); for (int I = 0; I <5; I ++) {new Thread (new Runnable () {public void run () {System. out. println (Thread. currentThread (). getName () + "starts. "); try {startCdt. countDown (); startCdt. await (); // The Five threads created are waiting for startCdt count = 0 to continue executing.} catch (InterruptedException e) {e. printStackTrace ();} finally {endCdt. countDown (); // after each thread completes execution, the count value is reduced by 1System. out. println (Thread. currentThread (). getName () + "ends. ");}}}). start ();} endCdt. await (); // The main thread continues to execute when the value of endCdt is 0, that is, wait until the preceding five threads have been executed. out. println ("all threads end. ");}
The execution result is as follows:
Thread-1starts.Thread-3starts.Thread-4starts.Thread-2starts.Thread-0starts.Thread-0 ends.Thread-1 ends.Thread-3 ends.Thread-4 ends.Thread-2 ends.all threads end.
Although each sub-thread is executed immediately after it is created, when it is running to startCdt. await () is blocked and continues to be executed only when the counter value of startCdt is reduced to 0. Similarly, the main thread is executing to endCdt. await () is blocked and continues to be executed only when its counter is reduced to 0. If no endCdt. await () exists, the execution result is as follows:
Thread-1starts.Thread-4starts.Thread-0starts.all threads end.Thread-2starts.Thread-3starts.Thread-3 ends.Thread-1 ends.Thread-4 ends.Thread-0 ends.Thread-2 ends.