In some scenarios, we must wait for the thread execution to complete before proceeding to the next step. For example, some programs need to initialize some resources before starting execution. At this time, we can start a thread specifically to do the initialization task, and wait until the thread task is completed before executing other parts.
For this purpose, the Thread class provides us with the join() method. When we call this method using a thread object, the calling thread object will be delayed until the called object completes execution before starting execution.
In this section, the sample program demonstrates waiting for the initialization method to complete before performing other tasks.
know it
Follow the steps shown below to complete the sample program.
1. Create a class named DataSourcesLoader and implement the Runnable interface. The code is as follows:
Copy the code code as follows:
public class DataSourcesLoader implements Runnable {
2. Implement the run() method, print a message to the console to indicate the start of execution, then sleep for 4 seconds, and then print a message to the console to indicate the end of thread execution. The code is as follows:
Copy the code code as follows:
@Override
public void run() {
System.out.printf("Beginning data sources loading: %s/n",
new Date());
try {
TimeUnit.SECONDS.sleep(4);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.printf("Data sources loading has finished: %s/n",
new Date());
}
3. Create a class named NetworkConnectionsLoader and implement the Runnable interface. Implement the run() method. The code of this method is the same as the run() method of the DataSourcesLoader class, except that it sleeps for 6 seconds.
4. Implement the main class of the example and implement the main() method. The code is as follows:
Copy the code code as follows:
public class Main {
public static void main(String[] args) {
5. Create a DataSourcesLoader object and a Thread object to start its execution. The code is as follows:
Copy the code code as follows:
DataSourcesLoader dsLoader = new DataSourcesLoader();
Thread thread1 = new Thread(dsLoader, "DataSourcesLoader");
6. Create a NetworkConnectionsLoader object and a Thread object to start its execution. The code is as follows:
Copy the code code as follows:
NetworkConnectionsLoader ncLoader = new NetworkConnectionsLoader();
Thread thread2 = new Thread(ncLoader, "NetworkConnectionsLoader");
7. Call the start() method of the two Thread objects. The code is as follows:
Copy the code code as follows:
thread1.start();
thread2.start();
8. Call the join() method to wait for the two threads to complete their tasks. This method will throw InterruptedException, so catch this exception. The code is as follows:
Copy the code code as follows:
try {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
9. Print a sentence to the console to indicate the end of program execution. The code is as follows:
Copy the code code as follows:
System.out.printf("Main: Configuration has been loaded: %s/n",
new Date());
10. Run the program and check the execution effect.
know why
When running this example program, we can see two threads starting their execution. First, the DataSourcesLoader completes its execution; then, the NetworkConnectionsLoader completes its execution. At this point, the main thread continues its execution and then prints a termination message to the console.
never ending
Java provides two other overloaded join() methods:
Copy the code code as follows:
join(long milliseconds)
join(long milliseconds, long nanos)
The first method does not wait until the called to complete the task, but waits for the time specified by the parameter before starting execution; for example, if thread1 calls this method, thread1.join(1000), when the thread1 thread meets one of the following conditions will continue to execute:
1.thread2 completes its execution;
2.After 1000 milliseconds;
When one of these two conditions is true, the join() method will return and continue executing the original task.
The second method is very similar to the first method, except that it has an additional nanosecond time parameter.
Use doctrine
This article is translated from "Java 7 Concurrency Cookbook" (D Gua Ge stole it as "Java7 Concurrency Example Collection") and is only used as learning materials. It may not be used for any commercial purposes without authorization.
Small success
The complete version of the sample code used in this section.
The complete code of the DataSourcesLoader class is as follows:
package com.diguage.books.concurrencycookbook.chapter1.recipe6;
import java.util.Date;
import java.util.concurrent.TimeUnit;
/**
* Date: 2013-09-19
* Time: 09:15
*/
public class DataSourcesLoader implements Runnable {
@Override
public void run() {
System.out.printf("Beginning data sources loading: %s/n",
new Date());
try {
TimeUnit.SECONDS.sleep(4);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.printf("Data sources loading has finished: %s/n",
new Date());
}
}
Complete code of NetworkConnectionsLoader class
Copy the code code as follows:
package com.diguage.books.concurrencycookbook.chapter1.recipe6;
import java.util.Date;
import java.util.concurrent.TimeUnit;
/**
* Date: 2013-09-19
* Time: 09:21
*/
public class NetworkConnectionsLoader implements Runnable {
@Override
public void run() {
System.out.printf("Beginning data sources loading: %s/n",
new Date());
try {
TimeUnit.SECONDS.sleep(6);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.printf("Data sources loading has finished: %s/n",
new Date());
}
}
The complete code of Main class
Copy the code code as follows:
package com.diguage.books.concurrencycookbook.chapter1.recipe6;
import java.util.Date;
/**
* Date: 2013-09-19
* Time: 09:25
*/
public class Main {
public static void main(String[] args) {
DataSourcesLoader dsLoader = new DataSourcesLoader();
Thread thread1 = new Thread(dsLoader, "DataSourcesLoader");
NetworkConnectionsLoader ncLoader = new NetworkConnectionsLoader();
Thread thread2 = new Thread(ncLoader, "NetworkConnectionsLoader");
thread1.start();
thread2.start();
try {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.printf("Main: Configuration has been loaded: %s/n",
new Date());
}
}