A new thread can be simply started by invoking the
start
method on a corresponding object. Sometimes it may be also necessary to manage the lifecycle of a thread when its work rather than just start it and then forget.In this lesson we will consider two commonly used methods in multithreading programming:
sleep()
and join()
. Both methods may throw a checked InterruptedException
that is omitted here for brevity.Sleeping
The static method
Thread.sleep()
causes the currently executing thread to suspend execution for the specified number of milliseconds. This is an efficient means of making processor time available to the other threads of an application or other applications that might be running on a computer.We will often use this method throughout the course to simulate expensive calls and difficult tasks.
System.out.println("Started");
Thread.sleep(2000L); // suspend current thread for 2000 millis
System.out.println("Finished");
Let's a little explain this code. Firstly, it prints "Started", then the current thread is suspended for 2000 milliseconds (it may be actually longer, but not less). After that, the thread wakes up and prints "Finished".
Another way to sleep the current thread is to use the special class
TimeUnit
from the package java.util.concurrent:
TimeUnit.MILLISECONDS.sleep(2000)
performsThread.sleep
for 2000 milliseconds;TimeUnit.SECONDS.sleep(2)
performsThread.sleep
for 2 seconds;
NANOSECONDS
, MICROSECONDS
, MILLISECONDS
, SECONDS
, MINUTES
, HOURS
, DAYS
.Joining
The
join
method forces the current thread to wait for completion of another thread on which the method was called. In the following example, the string "do something else" will not be printed until the thread terminates.Thread thread = ...
thread.start(); // start thread
System.out.println("Do something useful");
thread.join(); // waiting for thread to die
System.out.println("Do something else");
The overloaded version of this method takes a waiting time in milliseconds.
thread.join(2000L);
This can be useful not to wait too long or infinitely if the thread is hung.
Let's consider another example. The
Worker
class is developed to solve "a difficult task" simulated by the sleep:class Worker extends Thread {
@Override
public void run() {
try {
System.out.println("Starting a task");
Thread.sleep(2000L); // it solves a difficult task
} catch (Exception ignored) {
}
}
}
Here is the
main
method in which the main thread waits for completion of the worker
.public class JoiningExample {
public static void main(String []args) throws InterruptedException {
Thread worker = new Worker();
worker.start(); // start the worker
Thread.sleep(100L);
System.out.println("Do something useful");
worker.join(3000L); // waiting for the worker
System.out.println("The program stopped");
}
}
The main thread waits for
worker
and cannot print the message "The program stopped" until the worker terminates. But the messages "Starting a task" and "Do something useful" may be in any order.First possible output:
Starting a task
Do something useful
The program stopped
Second possible output:
Do something useful
Starting a task
The program stopped