You'll often come across this exception being thrown from functions. When a thread wait()-s or sleep()-s then one way for it to give up waiting/sleeping is to be interrupted. If a thread is interrupted while waiting/sleeping, it'll wake up and immediately throw Interrupted exception.
The thread class exposes the interrupt()
method which can be used to interrupt a thread that is blocked in a sleep()
or wait()
call. Note that invoking the interrupt method only sets a flag that is polled periodically by sleep or wait to know the current thread has been interrupted and an interrupted exception should be thrown.
Below is an example, where a thread is initially made to sleep for an hour but then interrupted by the main thread.
public void example() throws InterruptedException {
final Thread sleepyThread = new Thread(() -> {
try {
System.out.println("I am too sleepy... Let me sleep for an hour.");
Thread.sleep(1000 * 60 * 60);
} catch (InterruptedException ie) {
//Once the interrupted exception is thrown, the interrupt status/flag is cleared
System.out.println("The interrupt flag is cleard : " + Thread.interrupted() + " " + Thread.currentThread().isInterrupted());
Thread.currentThread().interrupt();
System.out.println("Oh someone woke me up ! ");
System.out.println("The interrupt flag is set now : " + Thread.currentThread().isInterrupted() + " " + Thread.interrupted());
}
});
sleepyThread.start();
System.out.println("About to wake up the sleepy thread ...");
sleepyThread.interrupt();
System.out.println("Woke up sleepy thread ...");
sleepyThread.join();
}
<aside>
💡 Note that there are two methods to check for the interrupt status of a thread. One is the static method Thread.interrupted()
and the other is Thread.currentThread().isInterrupted().
The important difference between the two is that the static method would return the interrupt status and also clear it at the same time. On line 16 we deliberately call the object method first followed by the static method. If we reverse the ordering of the two method calls on line 16 the output for the line would be true and false, instead of true and true.
</aside>
The volatile concept is specific to Java. Its easier to understand volatile, if you understand the problem it solves.
If you have a variable say a counter that is being worked on by a thread, it is possible the thread keeps a copy of the counter variable in the CPU cache and manipulates it rather than writing to the main memory. The JVM will decide when to update the main memory with the value of the counter, even though other threads may read the value of the counter from the main memory and may end up reading a stale value.
If a variable is declared volatile then whenever a thread writes or reads to the volatile variable, the read and write always happen in the main memory. As a further guarantee, all the variables that are visible to the writing thread also get written-out to the main memory alongside the volatile variable. Similarly, all the variables visible to the reading thread alongside the volatile variable will have the latest values visible to the reading thread.
Volatile comes into play because of multiples levels of memory in hardware architecture required for performance enhancements. If there's a single thread that writes to the volatile variable and other threads only read the volatile variable then just using volatile is enough, however, if there's a possibility of multiple threads writing to the volatile variable then "synchronized" would be required to ensure atomic writes to the variable.