针对想要结束的线程,Java提供了中断机制。中断机制的一个特性是线程对象多个线程对象需要检查是否已被中断,然后它们能够决定是否响应结束请求。单一线程对象能够忽略中断,继续执行任务。
在本节范例中,创建一个线程,使用中断机制,强迫其在五秒后结束。
准备工作
本范例通过Eclipse开发工具实现。如果使用诸如NetBeans的开发工具,打开并创建一个新的Java项目。
实现过程
通过如下步骤完成范例:
-
创建PrimeGenerator类,继承Thread类:
public class PrimeGenerator extends Thread {
-
重写run()方法,包括一个无限运行的循环。在这个循环中,从1 开始递增数字。计算每个数字是否未质数,如果是的话,输出到控制台中:
@Override public void run(){ long number = 1L; while(true){ if(isPrime(number)){ System.out.printf("Number %d is Prime\n", number); }
-
每处理一个数字后,检查线程是否被名为isInterrupted()的方法中断。如果此方法返回true,表明线程已被中断。在这种情况下,在控制台中输出一条信息,然后结束线程执行:
if(isInterrupted()) { System.out.printf("The Prime Generator has been Interrupted"); return; } number ++ ; } }
-
实现isPrime()方法。代码可在本章中“创建、运行线程,设置线程属性”小节中得到。
-
现在实现主类。创建一个包含main()方法的Main类:
public class Main { public static void main(String[] args) {
-
创建PrimeGenerator类对象并启动:
Thread task = new PrimeGenerator(); task.start();
-
等待五秒后,中断PrimeGenerator线程:
try{ Thread.sleep(5000); }catch(InterruptedException e){ e.printStackTrace(); } task.interrupt();
-
然后,在控制台中输出中断的线程状态信息。这段代码的输出结果取决于是否在线程结束执行之前或之后:
System.out.printf("Main: Status of the Thread: %s\n", task.getState()); System.out.printf("Main: isInterrupted: %s\n", task.isInterrupted()); System.out.printf("Main: isAlive: %s\n", task.isAlive()); }
-
运行程序,查看结果。
工作原理
如下图所示,展现范例的执行结果。可以看到PrimeGenerator线程如何输出信息,同时当线程检测到已被中断时停止执行。
线程类包含一个存储布尔类型的属性,用来指出线程是否被中断。当调用线程的interrupt()方法时,设置此属性为true。isInterrupted()方法只用来返回这个属性值。
main()方法记录中断线程的状态信息。在这种情况下,因为代码在线程执行完成之前运行,状态为RUNNABLE,isInterrupted()方法返回值true,isAlive()返回值也是true。如果中断线程在代码块运行之前执行完成(例如,休眠主线程一秒钟),isInterrupted()和isAlive()将返回false。
扩展学习
线程类还有一种方法检查线程是否已被中断。interrupted()静态方法,用来检查当前线程是否已被中断。
isInterrupted()和interrupted()方法有一个重要区别。isInterrupted()方法无法改变中断属性值,但是interrupted()方法能够设置属性值为false。
如同之前提到的,线程对象可以忽略它的中断,但这不是预期行为。