Java concurrent programming example of four: controlled thread interrupts

  • 2020-04-01 03:33:18
  • OfStack

In the previous section, "(link: #)," we explained how to interrupt an executing Thread and what we had to do with it in order to interrupt it. In general, we can use the interrupt mechanism described in the previous section. However, if a thread implements a complex algorithm assigned to multiple methods, or if there is a recursive call in a method call, we should use a better way to control thread interrupts. To do this, Java provides InterruptedException. When an interrupt request is detected, this exception can be thrown and caught in the run() method.

In this section, we'll use a thread to find files in the specified directory and its subdirectories to demonstrate controlling thread interruption by using InterruptedException.

learning

Follow the steps shown below to implement the sample program.

1. Create a class named FileSearch and implement the Runnable interface. The code is as follows:


public class FileSearch implements Runnable {

2. Declare two variables, one for the file name to be searched and the other for the directory to be initialized; Implement the constructor for the class and initialize the two variables you just declared with the constructor's arguments. The code is as follows:


private String initPath;
private String fileName; public FileSearch(String initPath, String fileName) {
    this.initPath = initPath;
    this.fileName = fileName;
}

3. Implement the run() method, which checks whether fileName is a path name. If so, the directoryProcess() method is called for processing. The directoryProcess() method throws InterruptedException, so we need to catch it. The code is as follows:


@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());
        }
    }
}

In the original, the method name mentioned is processDirectory(). However, according to the following procedure, it is a clerical error. So the correction.

4. Implement the directoryProcess() method. This method reads all files and subdirectories in the specified directory and processes them. For each directory, the method makes a recursive call to handle the directory specified by the parameter. For each file, this method invokes the fileProcess() method. After all the directories and files have been processed, the method checks to see if the thread is interrupted, which throws an InterruptedException. The code is as follows:


/**
 * Working with a directory
 *
 * @param file Directories that need to be processed
 * @throws InterruptedException
 */
private void directoryProcess(File file) throws InterruptedException {
    File[] list = file.listFiles();
    if (null != list) {
        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();
    }
}

5. Implement the fileProcess() method, which compares the file being processed with the file name you need to find. If the file names are the same, a message is printed in the console. The thread then checks to see if it is interrupted, and if so, throws InterruptedException. The code is as follows:


/**
 * Processed documents
 *
 * @param file Documents that need to be processed
 * @throws InterruptedException
 */
private void fileProcess(File file) throws InterruptedException {
    if (file.getName().equals(fileName)) {
        System.out.printf("%s : %sn",
                Thread.currentThread().getName(),
                file.getAbsolutePath());
    }     if (Thread.interrupted()) {
        throw new InterruptedException();
    }
}

6. Now, implement the main class of the example and implement the main() method. The code is as follows:

public class Main {
    public static void main(String[] args) {

7. Create and initialize the FileSearch object, then create a Thread object to perform the task. Then, start the thread. The code is as follows:

FileSearch fileSearch = new FileSearch("C:\", "autoexec.bat");
Thread thread = new Thread(fileSearch);
thread.start();

Wait ten seconds, then interrupt the thread. The code is as follows:


try {
    TimeUnit.SECONDS.sleep(10);
} catch (InterruptedException e) {
    e.printStackTrace();
} thread.interrupt();

9. Execute the example and see the results.

Know why

Here is the result of the thread execution. The output shows how the FileSearch aborts the thread execution when it detects an interrupt.


Thread-0 : C:autoexec.bat
Thread-0: The search has been interrupted

In this example, we use Java exceptions to control thread interrupts. When you run the example, the program detects whether the specified directory and its subdirectories contain the target files. For example, if you type \b\c\d, the program will recursively call the directoryProcess() method three times. When the thread detects that it is interrupted, it throws InterruptedException, and the program starts executing the run() method no matter how many recursive calls it makes.

endless

InterruptedException is normally thrown by a Java concurrent API, such as the sleep() method.

si

This article is a translation from the Java7 Concurrency Cookbook (D jago to Java7 Concurrency examples) and is intended for use only as a learning material. Not to be used in any commercial activities without authorization.

Small has becomes

Full code for the FileSearch class


package com.diguage.books.concurrencycookbook.chapter1.recipe4; import java.io.File; /**
 * Date: 2013-09-18
 * Time: 18:21
 */
public class FileSearch implements Runnable {
    private String initPath;
    private String fileName;     /**
     * Initializes the constructor
     *
     * @param initPath The directory to look for
     * @param fileName The name of the file to look for
     */
    public FileSearch(String initPath, String fileName) {
        this.initPath = initPath;
        this.fileName = fileName;
    }     @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());
            }
        }
    }     /**
     * Working with a directory
     *
     * @param file Directories that need to be processed
     * @throws InterruptedException
     */
    private void directoryProcess(File file) throws InterruptedException {
        File[] list = file.listFiles();
        if (null != list) {
            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();
        }
    }     /**
     * Processed documents
     *
     * @param file Documents that need to be processed
     * @throws InterruptedException
     */
    private void fileProcess(File file) throws InterruptedException {
        if (file.getName().equals(fileName)) {
            System.out.printf("%s : %sn",
                    Thread.currentThread().getName(),
                    file.getAbsolutePath());
        }         if (Thread.interrupted()) {
            throw new InterruptedException();
        }
    }
}

The complete code for the Main class


package com.diguage.books.concurrencycookbook.chapter1.recipe4; import java.util.concurrent.TimeUnit; /**
 * Date: 2013-09-18
 * Time: 19:28
 */
public class Main {
    public static void main(String[] args) {
        FileSearch fileSearch = new FileSearch("C:\", "autoexec.bat");
        Thread thread = new Thread(fileSearch);
        thread.start();         try {
            TimeUnit.SECONDS.sleep(10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }         thread.interrupt();
    }
}


Related articles: