在本节中,实现一个任务,查找指定目录以及其所有子目录下确定名称的文件。用来展示如何使用IterruptedException异常来控制线程中断。
准备工作
本范例通过Eclipse开发工具实现。如果使用诸如NetBeans的开发工具,打开并创建一个新的Java项目。
实现过程
通过如下步骤完成范例:
-
创建FileSearch类,指定其实现Runnable接口:
public class FileSearch implements Runnable {
-
定义两个私有属性:分别是将要寻找的文件名称和初始目录路径。实现此类的构造函数,初始化两个属性:
private String initPath; private String fileName; public FileSearch(String initPath, String fileName){ this.initPath = initPath; this.fileName = fileName; }
-
实现FileSearch类的run()方法。判断fileName属性是否为目录,如果是,调用directoryProcess()方法,这个方法能够抛出IterruptedException异常,所以能够捕获到:
@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()); } } }
-
实现directoryProcess()方法。此方法将获得指定目录下的文件和子目录并进行处理。对每个目录,方法进行递归调用,遍历目录为参数。对每个文件,将调用fileProcess()方法。处理完所有文件和目录后,此方法判断线程是否已被中断,如果是的情况,会抛出一个IterruptedException异常:
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(); } }
-
实现fileProcess()方法。此方法将比较正在处理的文件和需要寻找的文件,如果名称相同,控制台会输出一条信息。比较过后,线程将判断它是否已被中断,如果是的情况,会抛出一个IterruptedException异常:
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(); } }
-
现在实现主类。创建一个包含main()方法的Main类:
public class Main { public static void main(String[] args) {
-
创建和初始化FileSearch类的对象和执行任务的线程,然后开始运行线程。这里使用的是Windows操作系统路径。如果用其他操作系统例如Linux或者iOS开发,更改相应路径:
FileSearch searcher = new FileSearch("C:\\Windows", "explorer.exe"); Thread thread = new Thread(searcher); thread.start();
-
等待10秒钟,中断线程:
try { TimeUnit.SECONDS.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } thread.interrupt(); }
-
运行程序,查看结果。
工作原理
下图展现范例的执行结果。可以看到FileSearch对象结束线程执行,以及当线程检测到已被中断时停止执行。
在范例中,我们使用Java异常来控制线程的中断。当运行范例时,程序遍历文件夹来判断是否存在对应文件。例如,如果进入\b\c\d文件夹,程序将递归三次调用directoryProcess()方法。当检测到线程已被中断,无论递归调用多少次,run()方法都会抛出IterruptedException异常,并且继续执行。
扩展学习
IterruptedException异常是由与并发API相关的Java方法抛出的,例如sleep()。如果线程在休眠的时候被中断(用interrupt()方法),就会抛出这个异常。
更多关注
本章中“中断线程”小节。