Java7并发示例集103:线程中断
一个多线程的Java程序,直到所有线程执行完成,整个程序才会退出。(需要注意的是,是所有非后台线程(non-daemon thread)执行完成;如果一个线程执行了System.exit()
方法,程序也会退出。)有时,你想中止一个线程的执行,例如你想退出程序,或者你想取消一个正在执行的任务等。
Java提供了中断机制,可以让我们显式地中断我们想中止执行的线程。中断机制的一个特征就是我们可以检查线程是否已经被中断,进而决定是否响应中止请求。线程也可以忽略中止请求,继续执行。
在本节,我们所开发的示例程序将会创建一个线程,五秒钟后,利用中断机制强制中止这个线程。
知其然
按照下面步骤所示,完成示例程序。
-
创建一个名为PrimeGenerator
的类,并且继承Thread
类。代码如下:
1 | public class PrimeGenerator extends Thread { |
-
重写run()
方法,在方法中添加一个无限循环,在循环内,通过计算来检查从1开始的连续正整数是否为素数。如果是,则打印到控制台。代码如下:
6 | System.out.printf( "Number %d \tis Prime." , number); |
-
在处理一个数字之后,通过调用isInterrupted()
方法来检查线程是否被中断。如果该方法返回true
,则向控制台打印一句话,然后中止线程执行。代码如下:
2 | System.out.println( "The Prime Generator has been Interrupted" ); |
-
实现isPrime()
方法,该方法用于判断参数是否为素数,如果是则返回true
,否则返回false
。代码如下:
04 | * @param number 需要判断的数字 |
07 | private boolean isPrime( long number) { |
12 | for ( int i = 2 ; i < number; i++) { |
13 | if ((number % i) == 0 ) { |
-
现在,实现示例程序的主类,Main
类,同时实现main()
方法。代码如下:
2 | public static void main(String[] args) { |
-
创建一个PrimeGenerator
对象,并且启动该线程。代码如下:
1 | Thread task = new PrimeGenerator(); |
-
等待五秒钟,然后中止该线程。代码如下:
2 | TimeUnit.SECONDS.sleep(5L); |
3 | } catch (InterruptedException e) { |
-
运行该示例,查看结果。
知其所以然
下面的是示例程序执行的打印片段。我们从打印出的字符可以看出PrimeGenerator
线程是如何打印输出信息以及当检测到线程被中断时,如何中止其执行的。
6 | The Prime Generator has been Interrupted |
Thread
有一个布尔型的熟悉,来表明线程是否被中断。当调用interrupt()
方法时,就是将其设置为true
。而isInterrupted()
方法则是返回该属性的当前值。
永无止境
Thread
还有一个可以检查线程是否中断的方法:即静态方法interrupted()
,可以检查当前正在执行的线程是否被中断。
isInterrupted()
方法和interrupted()
方法有非常大的不同。前者不会改变线程是否中断的属性值;而后者则可以将其值设置为false
。interrupted()
是一个静态方法;平时开发推荐使用isInterrupted()
方法。
正如前面所述,线程可以忽略中断请求而继续执行。但是,这并不是我们想要的结果。
拿来主义
本文是从 《Java 7 Concurrency Cookbook》 (D瓜哥窃译为 《Java7并发示例集》 )翻译而来,仅作为学习资料使用。没有授权,不得用于任何商业行为。
小有所成
示例程序所用的所有代码的完整版本。
PrimeGenerator类的完整代码
01 | package com.diguage.books.concurrencycookbook.chapter1.recipe3; |
08 | public class PrimeGenerator extends Thread { |
14 | if (isPrime(number)) { |
15 | System.out.printf( "Number %d \tis Prime.\n" , number); |
18 | if (isInterrupted()) { |
19 | System.out.println( "The Prime Generator has been Interrupted" ); |
30 | * @param number 需要判断的数字 |
33 | private boolean isPrime( long number) { |
38 | for ( int i = 2 ; i < number; i++) { |
39 | if ((number % i) == 0 ) { |
Main类的完整代码
01 | package com.diguage.books.concurrencycookbook.chapter1.recipe3; |
03 | import java.util.concurrent.TimeUnit; |
11 | public static void main(String[] args) { |
12 | Thread task = new PrimeGenerator(); |
16 | TimeUnit.SECONDS.sleep(5L); |
17 | } catch (InterruptedException e) { |