java 多线程基础之二:线程的中断(interrupt)

这篇博客记录怎么中断一个线程(interrupting a thread)
有时候,我们需要结束一个线程,因为你想终止程序,或者你想取消某个任务,而这个任务是在线程中执行的。

java 提供了 interruption 机制,在我们需要强制结束一个线程的时候使用.但在使用的时候,有一点是需要注意的,那就是要检查这个线程是否被 interrupted, 然后决定是否结束相应请求,或者忽略继续执行其他的,下面有一个简单的例子:创建了线程,在5秒钟之后,将采用interruption 机制强制结束他.

程序代码 程序代码

import java.util.concurrent.TimeUnit;

/**
* 一个判断质数的线程
* @author lzs *
*/
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++;
        }
    }

    /**
     *  计算一个数字是否为质数.
     * @param number : The number
     * @return A boolean value. True if the number is prime, false if not.
     */
    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;
    }
    
    public static void main(String[] args) {        
        Thread task=new PrimeGenerator();
        task.start();        
        try {
            TimeUnit.SECONDS.sleep(5);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }        
        // Interrupt the prime number generator
        task.interrupt();
    }

}


结果如下:
程序代码 程序代码

.....
Number 81701 is Prime
Number 81703 is Prime
Number 81707 is Prime
Number 81727 is Prime
Number 81737 is Prime
Number 81749 is Prime
The Prime Generator has been Interrupted


线程类有一个布尔型参数,确定一个现实被中断了,当调用 interrupt()  方法的时候,属性值被设置成 true,  而 isInterrutped() 方法只是用来返回这个布尔变量的值. 确定线程是否中断了.
isInterrupted() 是个静态方法,可以直接调用,判断当前线程是否被中断,

在线程中控制 interruption
上面的例子可以很简单的中断线程,但如果一个线程比较复杂,由很多方法组成,甚至有递归调用,这个时候就可以利用java 提供的 InterruptedException 来更好的处理。在你的调用方法里,你可以 抛出异常,而在线程的run() 方法里 catch 这个异常.

下面用了一个例子:在一个指定的文件夹里查找一个指定名字的文件,10秒钟之后,还没找到,就中断他.
程序代码 程序代码


import java.io.File;
import java.util.concurrent.TimeUnit;

/**
* 在目录中查找一个指定名字的文件
*/
public class FileSearch implements Runnable {

    /**
     * 要查找的目录
     */
    private String initPath;
    /**
     * 要查找的文件名称
     */
    private String fileName;
    
    public FileSearch(String initPath, String fileName) {
        this.initPath = initPath;
        this.fileName = fileName;
    }

    public void run() {
        File file = new File(initPath);
        if (file.isDirectory()) {
            try {
                directoryProcess(file);
            } catch (InterruptedException e) {
                System.out.printf("%s: The search has been interrupted",Thread.currentThread().getName());
            }
        }
    }

    /**
     * Method that process a directory
     * @param file  Directory to process
     * @throws InterruptedException If the thread is interrupted
     * 递归调用,在子目录下继续查找
     */
    private void directoryProcess(File file) throws InterruptedException {
        // 得到初始化的目录树
        File list[] = file.listFiles();
        if (list != null) {
            for (int i = 0; i < list.length; i++) {
                if (list[i].isDirectory()) {
                    // If is a directory, process it
                    directoryProcess(list[i]);
                } else {
                    // If is a file, process it
                    fileProcess(list[i]);
                }
            }
        }
        // Check the interruption
        if (Thread.interrupted()) {
            throw new InterruptedException();
        }
    }

    /**
     * Method that process a File
     * @param file : File to process
     * @throws InterruptedException If the thread is interrupted
     */
    private void fileProcess(File file) throws InterruptedException {
        // Check the name
        if (file.getName().equals(fileName)) {
            System.out.printf("%s : %s\n",Thread.currentThread().getName() ,file.getAbsolutePath());
        }
        // Check the interruption
        if (Thread.interrupted()) {
            throw new InterruptedException();
        }
    }
    
    public static void main(String[] args) {
        // 初始目录为C盘根目录,查找的文件名字为autoexec.bat
        FileSearch searcher=new FileSearch("C:\\","autoexec.bat");
        Thread thread=new Thread(searcher);
        
        // Starts the Thread
        thread.start();
        
        // Wait for ten seconds
        try {
            TimeUnit.SECONDS.sleep(10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }        
        // Interrupts the thread
        thread.interrupt();
    }

}


尽管里面有着递归调用,只要触发了 interrupt ,就会抛出 InterruptedException 异常,直接到 run() 去继续执行.

除非申明,文章均为一号门原创,转载请注明本文地址,谢谢!
文章来自: 本站原创
引用通告: 查看所有引用 | 我要引用此文章
Tags: java thread
相关日志:
评论: 0 | 引用: 0 | 查看次数: -
发表评论
昵 称:
密 码: 游客发言不需要密码.
内 容:
验证码: 验证码
选 项:
虽然发表评论不用注册,但是为了保护您的发言权,建议您注册帐号.