线程管理(三)线程的中断
一个多个线程在执行的Java程序,只有当其全部的线程执行结束时(更具体的说,是所有非守护线程结束或者某个线程调用System.exit()方法的时候),它才会结束运行。有时,你需要为了终止程序而结束一个线程,或者当程序的用户想要取消某个Thread对象正在做的任务。
Java提供中断机制来通知线程表明我们想要结束它。中断机制的特性是线程需要检查是否被中断,而且还可以决定是否响应结束的请求。所以,线程可以忽略中断请求并且继续运行。
在这个指南中, 我们将开发一个程序,它创建线程,然后在5秒之后,它会使用中断机制来强制结束线程。
package concurrency.study.chap01;
public class PrimeGenerator extends Thread {
@Override
public void run() {
long number = 1L;
while (true) {
if (isPrime(number)) {
System.out.printf("Number %d is Prime \n", number);
}
if (isInterrupted()) {
System.out.printf("The Prime Generator has been Interrupted\n");
return;
}
number++;
}
}
private boolean isPrime(long number) {
if (number <= 2) {
return true;
}
for (long i = 2; i < number; i++) {
if ((number % i) == 0) {
return false;
}
}
return true;
}
}
package concurrency.study.chap01;
public class PrimeGeneratorTest {
public static void main(String[] args) {
Thread task = new PrimeGenerator();
task.start();
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
task.interrupt();
}
}
Thread 类还有一个boolean类型的属性来表明线程是否被中断。当你调用线程的interrupt() 方法,就代表你把这个属性设置为 true。 而isInterrupted() 方法仅返回属性值。
hread 类还有其他可以检查线程是否被中断的方法。例如,这个静态方法interrupted()能检查正在运行的线程是否被中断。
isInterrupted()和interrupted() 方法有着很重要的区别。第一个不会改变interrupted属性值,但是第二个会设置成false。
interrupted() 方法是一个静态方法,建议使用isInterrupted()方法。在之前提到的,线程是可以忽略中断指令的,但是并这不是我们所期望的行为。
线程管理(四)操作线程的中断机制
在之前的指南里,你学习了如何中断执行线程和如何对Thread对象的中断控制。之前例子中的机制可以很容易中断的线程中使用。但是如果线程实现的是由复杂的算法分成的一些方法,或者它的方法有递归调用,那么我们可以用更好的机制来控制线程中断。为了这个Java提供了InterruptedException异常。当你检测到程序的中断并在run()方法内捕获,你可以抛这个异常。
在这个指南中, 我们将实现的线程会根据给定的名称在文件件和子文件夹里查找文件,这个将展示如何使用InterruptedException异常来控制线程的中断
1. 创建一个名为FileSearch的类,并一定要实现Runnable接口。
2. 声明2个为private的属性,一个是为了我们要查找的文件名和另一个是为了初始文件夹。为这个类实现一个构造函数,并初始化这些属性。
3. 为FileSearch类实现run()方法。 它会检测fileName属性是不是路径,如果它是,就调用processDirectory()方法。这个方法会抛出一个InterruptedException异常,所以我们应该要捕获它。
4. 实现 directoryProcess()方法。这个方法会获取文件夹的文件和子文件夹并处理他们。对于每个路径,这个方法会传递路径作为参数来循环调用。对于每个文件,它会调用fileProcess()方法。处理完全部的文件和文件夹后,它会检查线程有没有被中断,在这个例子,会抛出一个InterruptedException异常。
5. 实现 processFile()方法。这方法会比较文件的名字与我们要搜索的文件名。如果他们一样,就写一条信息到控制台。比较完后,线程会检查有没有被中断,在这里,它会抛出一个InterruptedException异常。
6. 现在, 让我们来实现例子的主类吧。实现一个Main类并包含main()方法。
7. 创建并初始一个FileSearch类的对象和一个执行它的任务的线程。然后,开始执行线程。
8. 等10秒然后中断线程。
9. 运行例子并查看结果
在这个例子, 我们使用Java异常来控制线程的中断。当你运行这个例子,程序开始浏览文件夹来检查他们是否含有那个文件。例如,如果你输入\b\c\d,那么程序会循环调用3次processDirectory()方法。当它检测到被中断时,它会抛出InterruptedException异常并继续执行方法,无论已经多少次循环调用。