Book Image

Java 9 Concurrency Cookbook, Second Edition - Second Edition

By : Javier Fernández González
Book Image

Java 9 Concurrency Cookbook, Second Edition - Second Edition

By: Javier Fernández González

Overview of this book

Writing concurrent and parallel programming applications is an integral skill for any Java programmer. Java 9 comes with a host of fantastic features, including significant performance improvements and new APIs. This book will take you through all the new APIs, showing you how to build parallel and multi-threaded applications. The book covers all the elements of the Java Concurrency API, with essential recipes that will help you take advantage of the exciting new capabilities. You will learn how to use parallel and reactive streams to process massive data sets. Next, you will move on to create streams and use all their intermediate and terminal operations to process big collections of data in a parallel and functional way. Further, you’ll discover a whole range of recipes for almost everything, such as thread management, synchronization, executors, parallel and reactive streams, and many more. At the end of the book, you will learn how to obtain information about the status of some of the most useful components of the Java Concurrency API and how to test concurrent applications using different tools.
Table of Contents (12 chapters)

Processing uncontrolled exceptions in a thread

A very important aspect in every programming language is the mechanism that helps you manage error situations in your application. The Java programming language, as almost all modern programming languages, implements an exception-based mechanism to manage error situations. These exceptions are thrown by Java classes when an error situation is detected. You can also use these exceptions or implement your own exceptions to manage the errors produced in your classes.

Java also provides a mechanism to capture and process these exceptions. There are exceptions that must be captured or re-thrown using the throws clause of a method. These exceptions are called checked exceptions. There are exceptions that don't have to be specified or caught. These are unchecked exceptions:

  • Checked exceptions: These must be specified in the throws clause of a method or caught inside them, for example, IOException or ClassNotFoundException.
  • Unchecked exceptions: These don't need to be specified or caught, for example, NumberFormatException.

When a checked exception is thrown inside the run() method of a thread object, we have to catch and treat them because the run() method doesn't accept a throws clause. When an unchecked exception is thrown inside the run() method of a thread object, the default behavior is to write the stack trace in the console and exit the program.

Fortunately, Java provides us with a mechanism to catch and treat unchecked exceptions thrown in a thread object to avoid ending the program.

In this recipe, we will learn this mechanism using an example.

Getting ready

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.

How to do it...

Follow these steps to implement the example:

  1. First of all, we have to implement a class to treat unchecked exceptions. This class must implement the UncaughtExceptionHandler interface and implement the uncaughtException() method declared in this interface. It's an interface enclosed in the Thread class. In our case, let's call this class ExceptionHandler and create a method to write information about Exception and Thread that threw it. The following is the code:
        public class ExceptionHandler implements UncaughtExceptionHandler { 
@Override
public void uncaughtException(Thread t, Throwable e) {
System.out.printf("An exception has been captured\n");
System.out.printf("Thread: %s\n",t.getId());
System.out.printf("Exception: %s: %s\n",
e.getClass().getName(),e.getMessage());
System.out.printf("Stack Trace: \n");
e.printStackTrace(System.out);
System.out.printf("Thread status: %s\n",t.getState());
}
}
  1. Now implement a class that throws an unchecked exception. Call this class Task, specify that it implements the Runnable interface, implement the run() method, and force the exception; for example, try to convert a String value into an int value:
        public class Task implements Runnable { 
@Override
public void run() {
int numero=Integer.parseInt("TTT");
}
}
  1. Now implement the main class of the example. Implement a class called Main with its main() method:
        public class Main { 
public static void main(String[] args) {
  1. Create a Task object and Thread to run it. Set the unchecked exception handler using the setUncaughtExceptionHandler() method and start executing the thread:
            Task task=new Task(); 
Thread thread=new Thread(task);
thread.setUncaughtExceptionHandler(new ExceptionHandler());
thread.start();
}
}
  1. Run the example and see the results.

How it works...

In the following screenshot, you can see the results of the execution of the example. The exception is thrown and captured by the handler that writes the information about Exception and Thread that threw it. This information is presented in the console:

When an exception is thrown in a thread and remains uncaught (it has to be an unchecked exception), the JVM checks whether the thread has an uncaught exception handler set by the corresponding method. If it does, the JVM invokes this method with the Thread object and Exception as arguments.

If the thread doesn't have an uncaught exception handler, the JVM prints the stack trace in the console and ends the execution of the thread that had thrown the exception.

There's more...

The Thread class has another method related to the process of uncaught exceptions. It's the static method setDefaultUncaughtExceptionHandler() that establishes an exception handler for all the thread objects in the application.

When an uncaught exception is thrown in the thread, the JVM looks for three possible handlers for this exception.

First it looks for the uncaught exception handler of the thread objects, as we learned in this recipe. If this handler doesn't exist, the JVM looks for the uncaught exception handler of ThreadGroup as explained in the Grouping threads and processing uncontrolled exceptions in a group of threads recipe. If this method doesn't exist, the JVM looks for the default uncaught exception handler, as we learned in this recipe.

If none of the handlers exits, the JVM writes the stack trace of the exception in the console and ends the execution of the Thread that had thrown the exception.

See also

  • The Grouping threads and processing uncontrolled exceptions in a group of threads recipe of this chapter