-
Book Overview & Buying
-
Table Of Contents
-
Feedback & Rating

Java 9 Concurrency Cookbook, Second Edition
By :

In some situations, we will have to wait for the end of the execution of a thread (the run()
method ends its execution). For example, we may have a program that will begin initializing the resources it needs before proceeding with the rest of the execution. We can run initialization tasks as threads and wait for their finalization before continuing with the rest of the program.
For this purpose, we can use the join()
method of the Thread
class. When we call this method using a thread object, it suspends the execution of the calling thread until the object that is called finishes its execution.
In this recipe, we will learn the use of this method with an initialization example.
The example for this recipe has been implemented using the Eclipse IDE. If you use Eclipse or a different IDE, such as NetBeans, open it and create a new Java project.
Follow these steps to implement the example:
DataSourcesLoader
and specify that it implements the Runnable
interface:public class DataSourcesLoader implements Runnable {
run()
method. It writes a message to indicate that it starts its execution, sleeps for 4 seconds, and writes another message to indicate that it ends its execution:@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()); }
NetworkConnectionsLoader
and specify that it implements the Runnable
interface. Implement the run()
method. It will be equal to the run()
method of the DataSourcesLoader
class, but it will sleep for 6 seconds.Main
that contains the main()
method:public class Main { public static void main(String[] args) {
DataSourcesLoader
class and a thread to run it:DataSourcesLoader dsLoader = new DataSourcesLoader(); Thread thread1 = new Thread(dsLoader,"DataSourceThread");
NetworkConnectionsLoader
class and a thread to run it:NetworkConnectionsLoader ncLoader = new NetworkConnectionsLoader(); Thread thread2 = new Thread(ncLoader,"NetworkConnectionLoader");
start()
method of both the thread objects:thread1.start(); thread2.start();
join()
method. This method can throw an InterruptedException
exception, so we have to include the code to catch it:try { thread1.join(); thread2.join(); } catch (InterruptedException e) { e.printStackTrace(); }
System.out.printf("Main: Configuration has been loaded: %s\n", new Date());
When you run this program, you would understand how both the thread objects start their execution. First, the DataSourcesLoader
thread finishes its execution. Then, the NetworkConnectionsLoader
class finishes its execution. At this moment, the main
thread object continues its execution and writes the final message.
Java provides two additional forms of the join()
method:
join (long milliseconds)
join (long milliseconds, long nanos)
In the first version of the join()
method, instead of indefinitely waiting for the finalization of the thread called, the calling thread waits for the milliseconds specified as the parameter of the method. For example, if the object thread1
has thread2.join(1000)
, thread1
suspends its execution until one of these two conditions are met:
thread2
has finished its executionWhen one of these two conditions is true
, the join()
method returns. You can check the status of the thread to know whether the join()
method was returned because it finished its execution or because the specified time had passed.
The second version of the join()
method is similar to the first one, but it receives the number of milliseconds and nanoseconds as parameters.