Since we are aware how to create threads now it’s time to observe some critical thread methods.
Method interrupt():
Consider a long running thread. If we invoke the interrupt method of this thread, we are basically telling the thread to stop executing whatever it is doing and instead execute a different code. This “different code” is defined inside the catch block which is handling “InterruptedException” exception.
To achieve this, we wrap the code defined inside the “run()” method in a try catch block and then handle the InterruptedException.
As per below code, if we invoke customThread.interrupt() before 5000ms sleep time is over, the code in the exception block is executed skipping the remaining code in try block. Try changing the sleep timer from 2000ms to 7000ms and observe the difference.
public static void main(String[] args) throws InterruptedException {
Thread customThread = new Thread(() -> {
Thread.currentThread().setName("Custom-Thread");
try {
Thread.sleep(5000);
System.out.println("Printing message from custom thread if not interrupted before 5000ms.");
} catch (InterruptedException e) {
System.out.println("Message printed if thread is interrupted.");
}
});
customThread.start();
Thread.sleep(2000); // change this one
customThread.interrupt();
}
Output of above code is:
Message printed if thread is interrupted.
Method join():
When we invoke the join() method of a particular thread, we are stating that the remaining code of the current thread will only be executed after the thread whose join method is invoked is finished.
Even in real world scenario, when we say join we are basically considering at least 2 entities or objects. In case of join() method the first thread will be the one whose join method is invoked and since join() method don’t have any arguments to pass a thread object current thread will become the second thread or the follower.
As per the code below, print statements of customThread will be executed first followed by main thread print statements.
public static void main(String[] args) throws InterruptedException {
Thread customThread = new Thread(() -> {
Thread.currentThread().setName("Custom-Thread");
try {
Thread.sleep(2000);
System.out.println("Printing message from custom thread.");
} catch (InterruptedException e) {
System.out.println("Message printed if thread is interrupted.");
}
});
customThread.start();
customThread.join();
System.out.println("Main thread statement executed after custom thread.");
}
Output of above code is:
Printing message from custom thread.
Main thread statement executed after custom thread.
Method setDaemon(true):
You can specify a thread as a daemon thread using setDaemon() method and passing “true” as an argument. These threads are meant to perform background tasks independently and JVM will not wait for their completion during exit.
As per below code snippet we have thread with sleep time of 5000ms. Since it is marked as daemon(setDaemon(true) our application will only log main thread print statement and exit. If we remove the setDaemon(true) line, the application will wait 5000ms and log statements from both custom thread and main thread before exiting.
public static void main(String[] args) throws InterruptedException {
Thread customThread = new Thread(() -> {
Thread.currentThread().setName("Custom-Thread");
try {
Thread.sleep(5000);
System.out.println("Printing message from custom thread.");
} catch (InterruptedException e) {
System.out.println("Message printed if thread is interrupted.");
}
});
customThread.setDaemon(true); //remove this line
customThread.start();
System.out.println("Main thread statement on exit.");
}
}
Output of above code is:
Main thread statement on exit.