1.4 线程的中断
如果一个Java程序有不止一个执行线程,当所有线程都运行结束的时候,这个Java程序才能运行结束;更确切地说应该是所有的非守护线程运行结束时,或者其中一个线程调用了System.exit()方法时,这个Java程序才运行结束。如果你想终止一个程序,或者程序的某个用户试图取消线程对象正在运行的任务,就需要结束这个线程。
Java提供了中断机制,我们可以使用它来结束一个线程。这种机制要求线程检查它是否被中断了,然后决定是不是响应这个中断请求。线程允许忽略中断请求并且继续执行。
在本节中,我们将开发程序来创建一个线程,使其运行5秒钟后再通过中断机制强制使其终止。
准备工作
本节的范例是在Eclipse IDE里完成的。无论你使用Eclipse还是其他的IDE(比如NetBeans),都可以打开这个IDE并且创建一个新的Java工程。
范例实现
按照接下来的步骤实现本节的范例。
1.创建一个名为PrimeGenerator的类,并继承Thread类。
``
public class PrimeGenerator extends Thread{``
2.覆盖run()方法,并在方法体内包含一个无限循环。在每次循环中,我们将处理从1开始的连续数。对每个数字,我们将计算它是不是一个质数,如果是的话就打印到控制台。
@Override
public void run() {
long number=1L;
while (true) {
if (isPrime(number)) {
System.out.printf("Number %d is Prime",number);
}```
3.一个数字处理完后,调用isInterrupted()方法来检查线程是否被中断。如果isInterrupted()返回值是true,就写一个信息并且结束线程的执行。
if (isInterrupted()) {
System.out.printf("The Prime Generator has been Interrupted");
return;
}
number++;
}
}`
4.实现isPrime()方法。isPrime()方法返回的是一个布尔值,如果接收到的参数是一个质数就返回true,否则就返回false。
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;
}```
5.现在我们来实现这个范例的主类Main,并且实现main()方法。
public class Main {
public static void main(String[] args) {`
6.创建PrimeGenerator类的一个对象,并且运行这个线程对象。
Thread task=new PrimeGenerator();
task.start();```
7.等待5秒钟后,中断PrimeGenerator线程。
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
task.interrupt();`
8.运行范例并查看结果。
工作原理
下面的截屏记录了上述范例的运行结果。通过这个图我们可以看到PrimeGenerator线程打印出的信息,并且看到当它被中断后就运行终止了。
Thread类有一个表明线程被中断与否的属性,它存放的是布尔值。线程的interrupt()方法被调用时,这个属性就会被设置为true。isInterrupted()方法只是返回这个属性的值。
更多信息
还有一个方法可以检查线程是否已被中断,即Thread类的静态方法interrupted(),用来检查当前执行的线程是否被中断。
isInterrupted()和interrupted()方法有一个很大的区别。isInterrupted()不能改变interrupted属性的值,但是后者能设置interrupted属性为false。因为interrupted()是一个静态方法,更推荐使用isInterrupted()方法。
像之前提到的,线程可以忽略中断,但并不是预期的行为。