Java 7 Concurrency Cookbook 翻译 第一章 线程管理之二
三、中断一个线程
一个拥有多个线程的Java程序要结束,需要满足两个条件之一:一是所有的非后台线程都执行结束了;二是某个线程执行了 System.exit() 方法。当你想要终结一个运行中的Java程序或者程序的用户想要取消一个线程正在执行的任务时,你都需要结束一个线程。
Java提供中断机制来表明我们想要终止一个线程。这个机制的核心是线程必须要检查自己是否被中断,而且线程自己决定是否响应中断请求。线程可以忽略该中断请求而继续执行。
在本秘诀中,我们将开发一个程序,这个程序创建线程,5秒后使用中断机制来结束线程。
public class Main {
public static void main(String[] args) {
Thread task = new PrimeGenerator();
task.start();
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
task.interrupt();
}
}
public class PrimeGenerator extends Thread {
@Override
public void run() {
long number = 1L;
while (true) {
if (isPrime(number)) {
System.out.printf("Number "+ number +" is Prime");
}
if (isInterrupted()) {
System.out.printf("The Prime Generator has been Interrupted");
return;
}
number++;
}
}
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;
}
}
在 Thread 类中有一个 boolean 类型的属性来表明该类对应的线程是否被中断。通过调用 Thread 对象的 interrupt() 方法,设置其对应的线程被中断。而 isInterrupted() 方法用来返回对应线程是否被中断的状态。
Thread 类还有一个静态方法 interrupted() 同样可以返回所在线程是否被中断的状态。但是该方法还有一个副作用:就是把线程的被中断状态重设为 false。
线程可以忽略其被中断的状态,但这通常不是好的编程习惯。
四、控制线程的中断状态
在上一个秘诀中,你学习了如何去中断一个线程和如何去控制线程的中断状态。如果你要中断执行的只是一个简单的线程,那么上一个秘诀就足够了。但是,如果该线程实现了一个分成多个方法的复杂算法,或者它含有实现了递归算法的方法,我们应该使用一种更好的机制去该线程的中断状态。为此,Java提供了 InterruptedException。当你在 run() 方法里发现了线程被中断时,你可以抛出并捕获该异常。
在本秘诀中,我们的线程在目录和其子目录中来寻找含有特定名称的文件,这个程序展示如何使用 InterruptedException 来控制线程的中断。
public class FileSearch implements Runnable{
private String initPath;
private String fileName;
public FileSearch(String initPath, String fileName) {
this.initPath = initPath;
this.fileName = fileName;
}
@Override
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());
}
}
}
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()) {
directoryProcess(list[i]);
} else {
fileProcess(list[i]);
}
}
}
if (Thread.interrupted()) {
throw new InterruptedException();
}
}
private void fileProcess(File file) throws InterruptedException {
if (file.getName().equals(fileName)) {
System.out.printf("%s : %s\n", Thread.currentThread().getName(),
file.getAbsolutePath());
}
if (Thread.interrupted()) {
throw new InterruptedException();
}
}
}
public class Main {
public static void main(String[] args) {
FileSearch search = new FileSearch("C:\\", "autoexec.bat");
Thread thread = new Thread(search);
thread.start();
try {
TimeUnit.SECONDS.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
thread.interrupt();
}
}
在这个例子中,我们使用异常机制来达到终止线程运行的目的。你运行此示例程序,程序开始遍历目录并查找特定的文件。一旦线程检查到自己被中断了,它就抛出 InterruptedException 异常,继续执行 run() 方法的代码,多层的递归调用对结果没实质影响。
Java并发API中的 sleep() 方法也有可能抛出 InterruptedException异常。
笔者总结:本秘诀本质还是线程自己检查是否被中断,发现被中断后,通过抛出异常的方式直接跳转到了异常捕获代码处,是否多层递归对此异常跳转机制没影响。
重要:本系列翻译文档也会在本人的微信公众号(此山是我开)第一时间发布,欢迎大家关注。
Java 7 Concurrency Cookbook 翻译 第一章 线程管理之二的更多相关文章
- Java 7 Concurrency Cookbook 翻译 第一章 线程管理之一
一.简介 在计算机的世界里,当我们谈论并发时,我们指的是一系列的任务同时运行于一个计算机中.这里说的同时运行,在计算机拥有多于一个处理器或者是一个多核处理器的时候才是真正的同时,在计算机只拥有单核处理 ...
- Java 7 Concurrency Cookbook 翻译 第一章 线程管理之六
十一.处理线程组中的未控制异常 每种编程语言一个很重要的特性就是其所提供的用来处理程序中错误情况的机制.Java语言和其他的现代语言一样,是提供了异常机制来处理对象程序中的错误.Java提供了很多的类 ...
- Java 7 Concurrency Cookbook 翻译 第一章 线程管理之五
九.使用线程本地变量 一个并发程序的最关键特征就是共享数据.这个特性在那些继承了 Thread 类或者 实现了 Runnable 接口的对象上显得更加重要. 如果你创建一个实现了 Runnable 接 ...
- Java 7 Concurrency Cookbook 翻译 第一章 线程管理之四
七.创建和运行一个后台线程 Java中有一种特别的线程叫做 deamon(后台) 线程.这类线程具有非常低的权限,并且只有在同一个程序中没有其他的正常线程在运行时才会运行.注意:当一个程序中只剩下后台 ...
- Java 7 Concurrency Cookbook 翻译 第一章 线程管理之三
五.睡眠和唤醒一个线程 有时,你会想要在一段特定的时间后再去中断线程的运行.举个例子,程序中的一个线程每一分钟检查一次传感器的状态,剩余的时间,线程应该处于空闲的状态.在这段空闲时间里,线程不会使用计 ...
- Java 7 Concurrency Cookbook 翻译 序言
在日常的Java代码开发过程中,很难免地有对多线程的需求,掌握java多线程和并发的机制也是Java程序员写出更健壮和高效代码的基础.笔者找寻国内已出版的关于Java多线程和并发的的中文书籍和翻译书籍 ...
- java的优点和误解 《java核心技术卷i》第一章
<java核心技术卷i>第一章主要内容包括三点: 1:Java白皮书的关键术语:描述Java的十一个关键字: 2:Java applet 3 :关于Java的常见误解 1:第一章:Ja ...
- web前端学习python之第一章_基础语法(二)
web前端学习python之第一章_基础语法(二) 前言:最近新做了一个管理系统,前端已经基本完成, 但是后端人手不足没人给我写接口,自力更生丰衣足食, 所以决定自学python自己给自己写接口哈哈哈 ...
- Android线程管理(二)——ActivityThread
线程通信.ActivityThread及Thread类是理解Android线程管理的关键. 线程,作为CPU调度资源的基本单位,在Android等针对嵌入式设备的操作系统中,有着非常重要和基础的作用. ...
随机推荐
- JavaWeb---总结(十三)使用Session防止表单重复提交
在平时开发中,如果网速比较慢的情况下,用户提交表单后,发现服务器半天都没有响应,那么用户可能会以为是自己没有提交表单,就会再点击提交按钮重复提交表单,我们在开发中必须防止表单重复提交. 一.表单重复提 ...
- RBAC权限设计实例
http://blog.csdn.net/painsonline/article/details/7183629 实现业务系统中的用户权限管理 B/S系统中的权限比C/S中的更显的重要,C/S系统因为 ...
- Yocto开发笔记之《错误记录》(QQ交流群:519230208)
QQ群:519230208,为避免广告骚扰,申请时请注明 “开发者” 字样 ============================================== 提问: 1. 怎样修改linu ...
- 【原】webpack结合gulp打包
在我前面的文章中,总结了一下自己学习webpack和gulp的一些东西.然而,在我的实际项目中,单独使用它们两者不能满足项目的需求.我遇到了下面的一些问题. 问题1: 因为我的图片需要放单cdn上面去 ...
- js021-Ajax与Comet
js021-Ajax与Comet 本章内容: 使用XMLHttpRequet对象 使用XMLHttpRequet事件 跨域Ajax通信的限制 Ajax技术的核心是XMLHttpRequet对象 21. ...
- 20145212 实验五《Java网络编程》
20145212 实验五<Java网络编程> 一.实验内容 1.运行下载的TCP代码,结对进行,一人服务器,一人客户端: 2.利用加解密代码包,编译运行代码,一人加密,一人解密: 3.集成 ...
- CodeForces 710CMagic Odd Square(经典-奇数个奇数&偶数个偶数)
题目链接:http://codeforces.com/problemset/problem/710/C 题目大意:输入一个奇数n,则生成n*n矩阵,要求矩阵的行.列还有斜着,所有元素之和为奇数. 解题 ...
- C#--中实现邮件发送
MailMessage mailmessage = new MailMessage(); mailmessage.To.Add("接受邮箱");//可以添加多个接收邮箱 mailm ...
- Unity时钟定时器插件
Unity时钟定时器插件 http://dsqiu.iteye.com/blog/2020603https://github.com/joserocha3/KillerCircles/blob/67a ...
- Robot Framework--05 案例设计之流程与数据分离
转自:http://blog.csdn.net/tulituqi/article/details/7651049 这一讲主要说一下案例设计了.还记得我们前面做的case么?先打开浏览器访问百度,输入关 ...