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)

Controlling the interruption of a thread

In the previous recipe, you learned how you can interrupt the execution of a thread and what you have to do to control this interruption in the thread object. The mechanism shown in the previous example can be used if the thread that can be interrupted is simple. But if the thread implements a complex algorithm divided into some methods or it has methods with recursive calls, we will need to use a better mechanism to control the interruption of the thread. Java provides the InterruptedException exception for this purpose. You can throw this exception when you detect the interruption of a thread and catch it in the run() method.

In this recipe, we will implement a task that will look for files with a determined name in a folder and in all its subfolders. This is to show how you can use the InterruptedException exception to control the interruption of a thread.

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. Create a class called FileSearch and specify that it implements the Runnable interface:
        public class FileSearch implements Runnable {
  1. Declare two private attributes: one for the name of the file we are going to search for and one for the initial folder. Implement the constructor of the class, which initializes these attributes:
        private String initPath; 
private String fileName;
public FileSearch(String initPath, String fileName) {
this.initPath = initPath;
this.fileName = fileName;
}
  1. Implement the run() method of the FileSearch class. It checks whether the attribute fileName is a directory; if it is, it calls the directoryProcess() method. This method can throw an InterruptedException exception, so we have to catch them:
        @Override 
public void run() {
File file = new File(initPath);
if (file.isDirectory()) {
try {
directoryProcess(file);
} catch (InterruptedException e) {
System.out.printf("%s: The search has been interrupted",
Thread.currentThread().getName());
}
}
}
  1. Implement the directoryProcess() method. This method will obtain the files and subfolders in a folder and process them. For each directory, the method will make a recursive call, passing the directory as a parameter. For each file, the method will call the fileProcess() method. After processing all files and folders, the method checks whether the thread has been interrupted; if yes, as in this case, it will throw an InterruptedException exception:
        private void directoryProcess(File file) throws
InterruptedException {
File list[] = file.listFiles();
if (list != null) {
for (int i = 0; i < list.length; i++) {
if (list[i].isDirectory()) {
directoryProcess(list[i]);
} else {
fileProcess(list[i]);
}
}
}
if (Thread.interrupted()) {
throw new InterruptedException();
}
}
  1. Implement the fileProcess() method. This method will compare the name of the file it's processing with the name we are searching for. If the names are equal, we will write a message in the console. After this comparison, the thread will check whether it has been interrupted; if yes, as in this case, it will throw an InterruptedException exception:
        private void fileProcess(File file) throws 
InterruptedException {
if (file.getName().equals(fileName)) {
System.out.printf("%s : %s\n",
Thread.currentThread().getName(),
file.getAbsolutePath());
}
if (Thread.interrupted()) {
throw new InterruptedException();
}
}
  1. Now let's implement the main class of the example. Implement a class called Main that contains the main() method:
        public class Main { 
public static void main(String[] args) {
  1. Create and initialize an object of the FileSearch class and thread to execute its task. Then start executing the thread. I have used a Windows operating system route. If you work with other operating systems, such as Linux or iOS, change the route to the one that exists on your operating system:
        FileSearch searcher = new FileSearch("C:\\Windows",
"explorer.exe");
Thread thread=new Thread(searcher);
thread.start();
  1. Wait for 10 seconds and interrupt the thread:
          try { 
TimeUnit.SECONDS.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
thread.interrupt();
}
  1. Run the example and see the results.

How it works...

The following screenshot shows the result of an execution of this example. You can see how the FileSearch object ends its execution when it detects that it has been interrupted.

In this example, we use Java exceptions to control the interruption of a thread. When you run the example, the program starts going through folders by checking whether they have the file or not. For example, if you enter in the \b\c\d folder, the program will have three recursive calls to the directoryProcess() method. When it detects that it has been interrupted, it throws an InterruptedException exception and continues the execution in the run() method, no matter how many recursive calls have been made.

There's more...

The InterruptedException exception is thrown by some Java methods related to a concurrency API, such as sleep(). In this case, this exception is thrown if the thread is interrupted (with the interrupt() method) when it's sleeping.

See also

  • The Interrupting a thread recipe of this chapter