In the previous section, "Threading interrupts," we explained how to break an executing thread and what we had to do with thread in order to get disconnected. In general, we can use the interrupt mechanism described in the previous section. However, if the thread implements a complex algorithm that is assigned to multiple methods, or if there is a recursive call in the method invocation, we should use a better way to control the interruption of the thread. To do this, Java provides a interruptedexception exception. When an interrupt request is detected, this exception can be thrown and captured in the run () method.
In this section, we will use a thread to find the file under the specified directory and its subdirectories to demonstrate the control of thread interrupts by using the interruptedexception exception.
Know it
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:
Copy Code code as follows:
public class FileSearch implements Runnable {
2. Declare two variables, one for the name of the file you want to find, one for the directory to initialize the lookup, the constructor for the class, and the constructor's arguments to initialize the two variables that you just declared. The code is as follows:
Copy Code code 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 invoked for processing. The Directoryprocess () method throws a Interruptedexception exception, so we need to catch the exception. The code is as follows:
Copy Code code 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 procedure below, it is a clerical error. So correct.
4. Implement the Directoryprocess () method. This method reads all files and subdirectories in the specified directory before processing. For each directory, the method makes a recursive call to handle the directory specified by the parameter. For each file, the 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 a Interruptedexception exception. The code is as follows:
Copy Code code as follows:
/**
* Processing a directory
*
* @param directory to be processed by file
* @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 files being processed and the file names that you want to find. If the file name is equal, a message is printed on the console. The thread then checks whether it is interrupted and, if so, throws a Interruptedexception exception. The code is as follows:
Copy Code code as follows:
/**
* Processing of documents
*
* @param files to be processed by file
* @throws interruptedexception
*/
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 ();
}
}
6. Now, to implement the main class of the sample and implement the main () method. The code is as follows:
Copy Code code as follows:
public class Main {
public static void Main (string[] args) {
7. Create and initialize the FileSearch object, and then create a thread object to perform the task. Then, start the thread. The code is as follows:
Copy Code code as follows:
FileSearch FileSearch = new FileSearch ("c:\\", "Autoexec.bat");
Thread thread = new Thread (FileSearch);
Thread.Start ();
8. Wait 10 seconds, then disconnect the thread. The code is as follows:
Copy Code code as follows:
try {
TimeUnit.SECONDS.sleep (10);
catch (Interruptedexception e) {
E.printstacktrace ();
}
Thread.Interrupt ();
9. Follow the example to see the results.
Know the reason why
The following is the result of thread execution. From the output, you can see how to abort a thread execution when FileSearch detects that it has been interrupted.
Copy Code code as follows:
Thread-0: C:\autoexec.bat
Thread-0: The search has been interrupted
In this example, we use Java exceptions to control the interruption of threads. When you run the example, the program detects whether the specified directory and its subdirectories contain the destination file. For example, if you enter \b\c\d, the program will recursively call the Directoryprocess () method three times. When a thread detects that it is interrupted, it throws a Interruptedexception exception, and the program starts executing the run () method regardless of the number of recursive calls executed.
Endless
Interruptedexception exceptions are typically thrown by the Java concurrency API, such as the Sleep () method.
Copycat
This article is from the "Java 7 Concurrency Cookbook" (D-Gua to "Java7 concurrent Sample Set") translation, only as learning materials used. No authorization shall be applied to any commercial act.
Small has become
Complete code for the FileSearch class
Copy Code code as follows:
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;
/**
* Initialize Constructor
*
* @param initpath directories that need to be looked up
* @param filename File name 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 ());
}
}
}
/**
* Processing a directory
*
* @param directory to be processed by file
* @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 files
*
& nbsp * @param file to be processed
* @throws interruptedexception
*/
& nbsp; 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 ();
}
}
}
The complete code for the main class
Copy Code code as follows:
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 ();
}
}