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

摘要: 这篇博客记录怎么中断一个线程(interrupting a thread)有时候,我们需要结束一个线程,因为你想终止程序,或者你想取消某个任务,而这个任务是在线程中执行的。java 提供了 interruption 机制,在我们需要强制结束一个线程的时候使用.但在使用的时候,有一点是需要注意的,那就是要检查这个线程是否被 interrupted, 然后决定是否结束相应请求,或者忽略继续执行其他的

这篇博客记录怎么中断一个线程(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 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() 去继续执行.

上一篇: java 多线程基础之一:多线程创建,执行,状态管理
下一篇: 简单的实现django的缓存
 评论 ( What Do You Think )
名称
邮箱
网址
评论
验证
   
 

 


  • 微信公众号

  • 我的微信

站点声明:

1、一号门博客CMS,由Python, MySQL, Nginx, Wsgi 强力驱动

2、部分文章或者资源来源于互联网, 有时候很难判断是否侵权, 若有侵权, 请联系邮箱:summer@yihaomen.com, 同时欢迎大家注册用户,主动发布无版权争议的 文章/资源.

3、鄂ICP备14001754号-3, 鄂公网安备 42280202422812号