Java Exception Handling

Java Exception Handling – InterruptedException

Moving along through our detailed Java Exception Handling series, today we’ll be going over the InterruptedException. An InterruptedException is thrown when a thread that is sleeping, waiting, or is occupied is interrupted.

In this article we’ll explore the InterruptedException by first looking at where it resides in the overall Java Exception Hierarchy. We’ll also look at some functional Java code samples that illustrate how working in multithreaded applications can potentially cause InterruptedExceptions. Let’s get going!

The Technical Rundown

All Java errors implement the java.lang.Throwable interface, or are extended from another inherited class therein. The full exception hierarchy of this error is:

Full Code Sample

Below is the full code sample we’ll be using in this article. It can be copied and pasted if you’d like to play with the code yourself and see how everything works.

When Should You Use It?

Since the InterruptedException is thrown when an active or sleeping thread is interrupted, this is typically only relevant when working with multithreaded applications. That is to say, since a single-threaded application would immediately halt all execution if the main thread was interrupted, you’ll actually be catching and responding to InterruptedExceptions only when there’s at least one additional thread in which to process the interruption.

With that, let’s jump right into our example code. To make things easier to track and log we’ve created the InterruptableThread class, which extends the base Thread class:

Nothing particularly fancy going on here. The constructor expects a single String name argument and passes that along to the base Thread constructor that also accepts a single String parameter for the name property. Otherwise, we implement the run method, since Thread implements the Runnable interface, which provides the abstract void run() method that will be executed when the thread starts. Within run() we output some messages to the log and call the sleep(2000) method to pause execution of this thread for two seconds. Otherwise, we catch any exceptions and that’s it.

For actually testing InterruptableThread instances we’ve also created the InterruptableThreadTest class. Since working with many default-valued parameters in Java can be annoying, rather than using multiple constructor overloads we’ve opted for a builder pattern, which we deeply dug into in a previous article. The linked article will explain a great deal more about the builder pattern if you’re curious, but the basic purpose is to simplify the process of changing many mutable (editable) properties, without the need to explicitly specify or modify any particular properties. We can alter only the properties we care about using chained method calls, while all other properties remain untouched.

The InterruptableThreadTesterBuilder class implements the builder pattern for the underlying InterruptableThreadTest class:

With the builder setup we can set the modified properties of InterruptableThreadTest in the primary constructor, then actually perform our logic and processing:

Here we create a secondary InterruptableThread and then start() it immediately. We also use the modified properties to determine if the main Thread should be slept, for how long, and if the secondary InterruptableThread should be interrupted.

Our Main.main(...) method instantiates an InterruptableThreadTestBuilder object and calls whatever property setters we need, before finally calling createInterruptableThreadTest(), which returns the fully-constructed InterruptableThreadTest instance:

In this first example we’re not interrupting the secondary thread and we’re not sleeping the main thread. Executing this test produces the following output:

Everything works as expected. The secondary thread is started, sleeps for two seconds, then completes. However, let’s try interrupting the secondary thread and see what happens:

Running this test throws an InterruptedException, because, as we intended, we explicitly interrupted the secondary thread during its two second sleep period:

In this case, you’ll recall that the InterruptableThreadTest constructor checks the shouldSleepMain property to determine if the main thread should also sleep, which occurs immediately after the secondary thread is started:

Thus, let’s run another test where we sleep the main thread for 2500 milliseconds (which is 500 milliseconds longer than the secondary thread is sleeping):

Executing this test no longer throws an InterruptedException and shows both threads sleeping their expected durations:

What’s also important to note is that we still attempt to interrupt the secondary thread by calling the interrupt() method. However, since the secondary thread is not in an active or sleep state, doing so doesn’t produce an InterruptedException.

The Airbrake-Java library provides real-time error monitoring and automatic exception reporting for all your Java-based projects. Tight integration with Airbrake’s state of the art web dashboard ensures that Airbrake-Java gives you round-the-clock status updates on your application’s health and error rates. Airbrake-Java easily integrates with all the latest Java frameworks and platforms like Spring, Maven, log4j, Struts, Kotlin, Grails, Groovy, and many more. Plus, Airbrake-Java allows you to easily customize exception parameters and gives you full, configurable filter capabilities so you only gather the errors that matter most.

Check out all the amazing features Airbrake-Java has to offer and see for yourself why so many of the world’s best engineering teams are using Airbrake to revolutionize their exception handling practices!