首页 > Java, 挨踢(IT) > Java7并发示例集103:线程中断

Java7并发示例集103:线程中断

2013年9月19日 发表评论 阅读评论 305 人阅读    

一个多线程的Java程序,直到所有线程执行完成,整个程序才会退出。(需要注意的是,是所有非后台线程(non-daemon thread)执行完成;如果一个线程执行了System.exit()方法,程序也会退出。)有时,你想中止一个线程的执行,例如你想退出程序,或者你想取消一个正在执行的任务等。

Java提供了中断机制,可以让我们显式地中断我们想中止执行的线程。中断机制的一个特征就是我们可以检查线程是否已经被中断,进而决定是否响应中止请求。线程也可以忽略中止请求,继续执行。

在本节,我们所开发的示例程序将会创建一个线程,五秒钟后,利用中断机制强制中止这个线程。

知其然

按照下面步骤所示,完成示例程序。

  1. 创建一个名为PrimeGenerator的类,并且继承Thread类。代码如下:

    1public class PrimeGenerator extends Thread {
  2. 重写run()方法,在方法中添加一个无限循环,在循环内,通过计算来检查从1开始的连续正整数是否为素数。如果是,则打印到控制台。代码如下:

    1@Override
    2public void run() {
    3    long number = 1L;
    4    while (true) {
    5        if (isPrime(number)) {
    6            System.out.printf("Number %d \tis Prime.", number);
    7        }
  3. 在处理一个数字之后,通过调用isInterrupted()方法来检查线程是否被中断。如果该方法返回true,则向控制台打印一句话,然后中止线程执行。代码如下:

    1        if (isInterrupted()) {
    2            System.out.println("The Prime Generator has been Interrupted");
    3            return;
    4        }
    5 
    6        number++;
    7    }
    8}
  4. 实现isPrime()方法,该方法用于判断参数是否为素数,如果是则返回true,否则返回false。代码如下:

    01/**
    02 * 判断参数是否为素数
    03 *
    04 * @param number 需要判断的数字
    05 * @return
    06 */
    07private boolean isPrime(long number) {
    08    if (number <= 2) {
    09        return true;
    10    }
    11 
    12    for (int i = 2; i < number; i++) {
    13        if ((number % i) == 0) {
    14            return false;
    15        }
    16    }
    17 
    18    return true;
    19}
  5. 现在,实现示例程序的主类,Main类,同时实现main()方法。代码如下:

    1public class Main {
    2    public static void main(String[] args) {
  6. 创建一个PrimeGenerator对象,并且启动该线程。代码如下:

    1Thread task = new PrimeGenerator();
    2task.start();
  7. 等待五秒钟,然后中止该线程。代码如下:

    1try {
    2    TimeUnit.SECONDS.sleep(5L);
    3} catch (InterruptedException e) {
    4    e.printStackTrace();
    5}
    6 
    7task.interrupt();
  8. 运行该示例,查看结果。

知其所以然

下面的是示例程序执行的打印片段。我们从打印出的字符可以看出PrimeGenerator线程是如何打印输出信息以及当检测到线程被中断时,如何中止其执行的。

1Number 43063    is Prime.
2Number 43067    is Prime.
3Number 43093    is Prime.
4Number 43103    is Prime.
5Number 43117    is Prime.
6The Prime Generator has been Interrupted

Thread有一个布尔型的熟悉,来表明线程是否被中断。当调用interrupt()方法时,就是将其设置为true。而isInterrupted()方法则是返回该属性的当前值。

永无止境

Thread还有一个可以检查线程是否中断的方法:即静态方法interrupted(),可以检查当前正在执行的线程是否被中断。

isInterrupted()方法和interrupted()方法有非常大的不同。前者不会改变线程是否中断的属性值;而后者则可以将其值设置为falseinterrupted()是一个静态方法;平时开发推荐使用isInterrupted()方法。

正如前面所述,线程可以忽略中断请求而继续执行。但是,这并不是我们想要的结果。

拿来主义

本文是从 《Java 7 Concurrency Cookbook》 (D瓜哥窃译为 《Java7并发示例集》 )翻译而来,仅作为学习资料使用。没有授权,不得用于任何商业行为。

小有所成

示例程序所用的所有代码的完整版本。

PrimeGenerator类的完整代码

01package com.diguage.books.concurrencycookbook.chapter1.recipe3;
02 
03/**
04 * Coder: D瓜哥,http://www.diguage.com/
05 * Date: 2013-09-18
06 * Time: 11:53
07 */
08public class PrimeGenerator extends Thread {
09 
10    @Override
11    public void run() {
12        long number = 1L;
13        while (true) {
14            if (isPrime(number)) {
15                System.out.printf("Number %d \tis Prime.\n", number);
16            }
17 
18            if (isInterrupted()) {
19                System.out.println("The Prime Generator has been Interrupted");
20                return;
21            }
22 
23            number++;
24        }
25    }
26 
27    /**
28     * 判断参数是否为素数
29     *
30     * @param number 需要判断的数字
31     * @return
32     */
33    private boolean isPrime(long number) {
34        if (number <= 2) {
35            return true;
36        }
37 
38        for (int i = 2; i < number; i++) {
39            if ((number % i) == 0) {
40                return false;
41            }
42        }
43 
44        return true;
45    }
46}

Main类的完整代码

01package com.diguage.books.concurrencycookbook.chapter1.recipe3;
02 
03import java.util.concurrent.TimeUnit;
04 
05/**
06 * Coder: D瓜哥,http://www.diguage.com/
07 * Date: 2013-09-18
08 * Time: 12:33
09 */
10public class Main {
11    public static void main(String[] args) {
12        Thread task = new PrimeGenerator();
13        task.start();
14 
15        try {
16            TimeUnit.SECONDS.sleep(5L);
17        } catch (InterruptedException e) {
18            e.printStackTrace();
19        }
20 
21        task.interrupt();
22    }
23}

 



作 者: D瓜哥,https://www.diguage.com/
原文链接:https://wordpress.diguage.com/archives/45.html
版权声明:非特殊声明均为本站原创作品,转载时请注明作者和原文链接。

分类: Java, 挨踢(IT) 标签:
  1. 本文目前尚无任何评论.
  1. 本文目前尚无任何 trackbacks 和 pingbacks.