线程管理(四)操作线程的中断机制

简介:

声明:本文是《 Java 7 Concurrency Cookbook 》的第一章, 作者: Javier Fernández González 译者:郑玉婷 校对:欧振聪

操作线程的中断机制

在之前的指南里,你学习了如何中断执行线程和如何对Thread对象的中断控制。之前例子中的机制可以很容易中断的线程中使用。但是如果线程实现的是由复杂的算法分成的一些方法,或者它的方法有递归调用,那么我们可以用更好的机制来控制线程中断。为了这个Java提供了InterruptedException异常。当你检测到程序的中断并在run()方法内捕获,你可以抛这个异常。

在这个指南中, 我们将实现的线程会根据给定的名称在文件件和子文件夹里查找文件,这个将展示如何使用InterruptedException异常来控制线程的中断。

准备

指南中的例子是使用Eclipse IDE 来实现的。如果你使用Eclipse 或者其他的IDE,例如NetBeans, 打开并创建一个新的java项目。

怎么做呢

按照这些步骤来实现下面的例子::

1.   创建一个名为FileSearch的类,并一定要实现Runnable接口。

public class FileSearch implements Runnable {

2.   声明2个为private的属性,一个是为了我们要查找的文件名和另一个是为了初始文件夹。为这个类实现一个构造函数,并初始化这些属性。

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

3.   为FileSearch类实现run()方法。 它会检测fileName属性是不是路径,如果它是,就调用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对象是如何执行的,当它检测到它被中断时。请看裁图:

在这个例子, 我们使用Java异常来控制线程的中断。当你运行这个例子,程序开始浏览文件夹来检查他们是否含有那个文件。例如,如果你输入\b\c\d,那么程序会循环调用3次processDirectory()方法。当它检测到被中断时,它会抛出InterruptedException异常并继续执行方法,无论已经多少次循环调用。

更多

InterruptedException 异常是由一些与并发API有关的Java方法,如sleep()抛出的。

参见

目录
相关文章
|
24天前
|
Java
线程池内部机制:线程的保活与回收策略
【10月更文挑战第24天】 线程池是现代并发编程中管理线程资源的一种高效机制。它不仅能够复用线程,减少创建和销毁线程的开销,还能有效控制并发线程的数量,提高系统资源的利用率。本文将深入探讨线程池中线程的保活和回收机制,帮助你更好地理解和使用线程池。
48 2
|
5月前
|
Java
并发编程的艺术:Java线程与锁机制探索
【6月更文挑战第21天】**并发编程的艺术:Java线程与锁机制探索** 在多核时代,掌握并发编程至关重要。本文探讨Java中线程创建(`Thread`或`Runnable`)、线程同步(`synchronized`关键字与`Lock`接口)及线程池(`ExecutorService`)的使用。同时,警惕并发问题,如死锁和饥饿,遵循最佳实践以确保应用的高效和健壮。
47 2
|
29天前
|
Java
在Java多线程编程中,`wait()` 和 `notify()/notifyAll()` 方法是线程间通信的核心机制。
在Java多线程编程中,`wait()` 和 `notify()/notifyAll()` 方法是线程间通信的核心机制。它们通过基于锁的方式,使线程在条件不满足时进入休眠状态,并在条件成立时被唤醒,从而有效解决数据一致性和同步问题。本文通过对比其他通信机制,展示了 `wait()` 和 `notify()` 的优势,并通过生产者-消费者模型的示例代码,详细说明了其使用方法和重要性。
25 1
|
6月前
|
存储 安全 Java
深入理解Java并发编程:线程安全与锁机制
【5月更文挑战第31天】在Java并发编程中,线程安全和锁机制是两个核心概念。本文将深入探讨这两个概念,包括它们的定义、实现方式以及在实际开发中的应用。通过对线程安全和锁机制的深入理解,可以帮助我们更好地解决并发编程中的问题,提高程序的性能和稳定性。
|
1月前
|
安全 Java 开发者
在多线程编程中,确保数据一致性与防止竞态条件至关重要。Java提供了多种线程同步机制
【10月更文挑战第3天】在多线程编程中,确保数据一致性与防止竞态条件至关重要。Java提供了多种线程同步机制,如`synchronized`关键字、`Lock`接口及其实现类(如`ReentrantLock`),还有原子变量(如`AtomicInteger`)。这些工具可以帮助开发者避免数据不一致、死锁和活锁等问题。通过合理选择和使用这些机制,可以有效管理并发,确保程序稳定运行。例如,`synchronized`可确保同一时间只有一个线程访问共享资源;`Lock`提供更灵活的锁定方式;原子变量则利用硬件指令实现无锁操作。
20 2
|
2月前
|
安全 Java API
Java线程池原理与锁机制分析
综上所述,Java线程池和锁机制是并发编程中极其重要的两个部分。线程池主要用于管理线程的生命周期和执行并发任务,而锁机制则用于保障线程安全和防止数据的并发错误。它们深入地结合在一起,成为Java高效并发编程实践中的关键要素。
32 0
|
3月前
探索操作系统中的线程同步机制
【8月更文挑战第31天】在多线程编程领域,理解并实现线程同步是至关重要的。本文通过浅显易懂的语言和生动的比喻,带你走进线程同步的世界,从互斥锁到信号量,再到条件变量,逐步揭示它们在协调线程行为中的作用。我们将一起动手实践,用代码示例加深对线程同步机制的理解和应用。
|
4月前
|
调度
【浅入浅出】Qt多线程机制解析:提升程序响应性与并发处理能力
在学习QT线程的时候我们首先要知道的是QT的主线程,也叫GUI线程,意如其名,也就是我们程序的最主要的一个线程,主要负责初始化界面并监听事件循环,并根据事件处理做出界面上的反馈。但是当我们只限于在一个主线程上书写逻辑时碰到了需要一直等待的事件该怎么办?它的加载必定会带着主界面的卡顿,这时候我们就要去使用多线程。
158 6
|
4月前
|
Java 调度
Java中的线程池机制详解
Java中的线程池机制详解
|
4月前
|
存储 前端开发 Java
(二)JVM成神路之剖析Java类加载子系统、双亲委派机制及线程上下文类加载器
上篇《初识Java虚拟机》文章中曾提及到:我们所编写的Java代码经过编译之后,会生成对应的class字节码文件,而在程序启动时会通过类加载子系统将这些字节码文件先装载进内存,然后再交由执行引擎执行。本文中则会对Java虚拟机的类加载机制以及执行引擎进行全面分析。