java 多线程基础之二:线程的中断(interrupt)
By:Roy.LiuLast updated:2013-01-19
这篇博客记录怎么中断一个线程(interrupting a thread)
有时候,我们需要结束一个线程,因为你想终止程序,或者你想取消某个任务,而这个任务是在线程中执行的。
java 提供了 interruption 机制,在我们需要强制结束一个线程的时候使用.但在使用的时候,有一点是需要注意的,那就是要检查这个线程是否被 interrupted, 然后决定是否结束相应请求,或者忽略继续执行其他的,下面有一个简单的例子:创建了线程,在5秒钟之后,将采用interruption 机制强制结束他.
有时候,我们需要结束一个线程,因为你想终止程序,或者你想取消某个任务,而这个任务是在线程中执行的。
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 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() 去继续执行.From:一号门
Previous:java 多线程基础之一:多线程创建,执行,状态管理
Next:简单的实现django的缓存
COMMENTS