zl程序教程

您现在的位置是:首页 >  后端

当前栏目

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

2023-09-11 14:17:37 时间

本节书摘来异步社区《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异常,因此必须捕获并处理这个异常。

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

 }

}
}`
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 img src="https://yqfile.alicdn.com/d6a979ab3224d3bda1841cb6961f84e870d48de9.png" width="" height="" 

 /div 

在本范例中,我们使用了Java异常来控制线程的中断。当运行这个范例时,程序将进入文件夹查找是否包含指定的文件。例如,如果要查找的文件夹目录结构是\b\c\d,这个程序将递归调用processDirectory()方法3次。不管递归调用了多少次,只要线程检测到它已经被中断了,就会立即抛出InterruptedException异常,然后继续执行run()方法。

更多信息

【Java SE】程序逻辑控制(下) 提到分支语句我们都不陌生,比如我们生活中都要面临着种种选择,而每个选择对应着不同的结果,我们的程序也是有许许多多的分支构成的,在Java中为我们提供了两种分支语句:if 和 switch语句,下面我们就来学习下这两个语句。
【Java SE】程序逻辑控制(上) 提到分支语句我们都不陌生,比如我们生活中都要面临着种种选择,而每个选择对应着不同的结果,我们的程序也是有许许多多的分支构成的,在Java中为我们提供了两种分支语句:if 和 switch语句,下面我们就来学习下这两个语句。
Java并发编程实战(线程控制操作详解) 在使用Java实际编程中,多线程可以说是无所不在,凡是需要并发执行的都可以用到它,一个应用程序中不用多线程将会是很糟糕的事情,所以掌握线程以及它的控制操作是非常重要的。
异步社区 异步社区(www.epubit.com)是人民邮电出版社旗下IT专业图书旗舰社区,也是国内领先的IT专业图书社区,致力于优质学习内容的出版和分享,实现了纸书电子书的同步上架,于2015年8月上线运营。公众号【异步图书】,每日赠送异步新书。