《Java程序员面试秘笈》—— 1.5 线程中断的控制

    xiaoxiao2024-05-20  135

    本节书摘来异步社区《Java 7并发编程实战手册》一书中的第1章,第1.5节,作者:【西】Javier Fernández González,更多章节内容可以访问云栖社区“异步社区”公众号查看。

    1.5 线程中断的控制

    通过上一节,你已经学会了如何去中断执行中的线程,也学会了如何在线程对象中去控制这个中断。上一个例子中使用的机制,可以使用在线程很容易被中断的情况下。但是,如果线程实现了复杂的算法并且分布在几个方法中,或者线程里有递归调用的方法,我们就得使用一个更好的机制来控制线程的中断。为了达到这个目的,Java提供了InterruptedException异常。当检查到线程中断的时候,就抛出这个异常,然后在run()中捕获并处理这个异常。

    在本节中,我们将实现线程类来完成下面的内容,它在一个文件夹及其子文件夹中寻找一个指定的文件。这个范例将示范如何用InterruptedException异常来控制线程的中断。

    准备工作本节的范例是在Eclipse IDE里完成的。无论你使用Eclipse还是其他的IDE(比如NetBeans),都可以打开这个IDE并且创建一个新的Java工程。

    范例实现按照接下来的步骤实现本节的范例。

    1.创建一个名为FileSearch的类,并且实现Runnable接口。``public class FileSearch implements Runnable {``2.声明两个私有属性,一个是我们将要查找的文件名称,另一个是初始文件夹。实现这个类的构造器,用来初始化这两个属性。

    private String initPath; private String fileName; public FileSearch(String initPath, String fileName) { this.initPath = initPath; this.fileName = fileName; }``` 3.在FileSearch中实现run()方法。它将检查fileName属性是不是一个目录,如果是,就调用processDirectory()方法。processDirectory()方法会抛出InterruptedException异常,因此必须捕获并处理这个异常。

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

    }}`4.实现directoryProcess()方法,这个方法会获取一个文件夹里的所有文件和子文件夹,并进行处理。对于每一个目录,这个方法将递归调用,并且用相应目录名作为传入参数。对于每个文件,这个方法将调用fileProcess()方法。处理完所有的文件和文件夹后,这个方法将检查线程是不是被中断了,如果是,就抛出InterruptedException异常。

    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(); } }``` 5.实现processFile()方法。这个方法将比较当前文件的文件名和要查找的文件名,如果文件名匹配,就将信息打印到控制台。做完比较后,线程将检查是不是被中断了,如果是,它将抛出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.现在,我们实现这个范例的主类。实现一个包含main()方法的Main类。

    public class Main { public static void main(String[] args) {``` 7.创建FileSearch类的一个对象,并用它作为传入参数来创建一个线程对象,然后启动线程执行任务。

    FileSearch searcher=new FileSearch("C:\","autoexec.bat");Thread thread=new Thread(searcher);thread.start();`8.等待10秒钟,然后中断线程。

    try { TimeUnit.SECONDS.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } thread.interrupt(); }``` 9.运行这个范例并查看结果。 工作原理 下面的截屏记录了范例的运行结果。你可以看到当FileSearch对象检测到它被中断之后就结束了运行。 <div style="text-align: center"><img src="https://yqfile.alicdn.com/d6a979ab3224d3bda1841cb6961f84e870d48de9.png" width="" height=""> </div> 在本范例中,我们使用了Java异常来控制线程的中断。当运行这个范例时,程序将进入文件夹查找是否包含指定的文件。例如,如果要查找的文件夹目录结构是\b\c\d,这个程序将递归调用processDirectory()方法3次。不管递归调用了多少次,只要线程检测到它已经被中断了,就会立即抛出InterruptedException异常,然后继续执行run()方法。 更多信息 相关资源:敏捷开发V1.0.pptx
    最新回复(0)