Thread interrupt() 方法的使用
2014-06-28 08:59
411 查看
原文地址:http://blog.csdn.net/biangren/article/details/7522583
interrupt()只是改变中断状态而已:
interrupt()不会中断一个正在运行的线程。这一方法实际上完成的是,在线程受到阻塞时抛出一个中断信号,这样线程就得以退出阻塞的状态。更确切的说,如果线程被Object.wait, Thread.join和Thread.sleep三种方法之一阻塞,那么,它将接收到一个中断异常(InterruptedException),从而提早地终结被阻塞状态.如果线程没有被阻塞,这时调用interrupt()将不起作用;仅仅是设置中断标志位为true
同时注意下面三个方法的区别:
publicvoid interrupt()
public static boolean interrupted():线程的中断状态由该方法清除
public boolean isInterrupted() :测试线程是否已经中断。线程的中断状态不受该方法的影响。
总结:
t.interrupt()不会中断正在执行的线程,只是将线程的标志位设置成true。但是如果线程在调用sleep(),join(),wait()方法时线程被中断,则这些方法会抛出InterruptedException,在catch块中捕获到这个异常时,线程的中断标志位已经被设置成false了,因此在此catch块中调用t.isInterrupted(),Thread.interrupted()始终都为false,
而t.isInterrupted与Thread.interrupted()的区别是API中已经说明很明显了,Thread.interrupted()假如当前的中断标志为true,则调完后会将中断标志位设置成false ,而t.isInterrupted对标志位不做任何处理
假如我们有一个任务如下,交给一个Java线程来执行,如何才能保证调用interrupt()来中断它呢?
Java代码
class ATask implements Runnable{
private double d = 0.0;
public void run() {
//死循环执行打印"I am running!" 和做消耗时间的浮点计算
while (true) {
System.out.println("I am running!");
for (int i = 0; i < 900000; i++) {
d = d + (Math.PI + Math.E) / d;
}
//给线程调度器可以切换到其它进程的信号
Thread.yield();
}
}
}
public class InterruptTaskTest {
public static void main(String[] args) throws Exception{
//将任务交给一个线程执行
Thread t = new Thread(new ATask());
t.start();
//运行一断时间中断线程
Thread.sleep(100);
System.out.println("****************************");
System.out.println("Interrupted Thread!");
System.out.println("****************************");
t.interrupt();
}
}
运行这个程序,我们发现调用interrupt()后,程序仍在运行,如果不强制结束,程序将一直运行下去,如下所示:
Java代码
......
I am running!
I am running!
I am running!
I am running!
****************************
Interrupted Thread!
****************************
I am running!
I am running!
I am running!
I am running!
I am running!
....
虽然中断发生了,但线程仍然在进行,离开线程有两种常用的方法:
抛出InterruptedException和用Thread.interrupted()检查是否发生中断,下面分别看一下这两种方法:
1.在阻塞操作时如Thread.sleep()时被中断会抛出InterruptedException(注意,进行不能中断的IO操作而阻塞和要获得对象的锁调用对象的synchronized方法而阻塞时不会抛出InterruptedException)
Java代码
class ATask implements Runnable{
private double d = 0.0;
public void run() {
//死循环执行打印"I am running!" 和做消耗时间的浮点计算
try {
while (true) {
System.out.println("I am running!");
for (int i = 0; i < 900000; i++) {
d = d + (Math.PI + Math.E) / d;
}
//休眠一断时间,中断时会抛出InterruptedException
Thread.sleep(50);
}
} catch (InterruptedException e) {
System.out.println("ATask.run() interrupted!");
}
}
}
程序运行结果如下:
Java代码
I am running!
I am running!
****************************
Interrupted Thread!
****************************
ATask.run() interrupted!
可以看到中断任务时让任务抛出InterruptedException来离开任务.
2.Thread.interrupted()检查是否发生中断.Thread.interrupted()能告诉你线程是否发生中断,并将清除中断状态标记,所以程序不会两次通知你线程发生了中断.
Java代码
class ATask implements Runnable{
private double d = 0.0;
public void run() {
//检查程序是否发生中断
while (!Thread.interrupted()) {
System.out.println("I am running!");
for (int i = 0; i < 900000; i++) {
d = d + (Math.PI + Math.E) / d;
}
}
System.out.println("ATask.run() interrupted!");
}
}
程序运行结果如下:
Java代码
I am running!
I am running!
I am running!
I am running!
I am running!
I am running!
I am running!
****************************
Interrupted Thread!
****************************
ATask.run() interrupted!
interrupt()只是改变中断状态而已:
interrupt()不会中断一个正在运行的线程。这一方法实际上完成的是,在线程受到阻塞时抛出一个中断信号,这样线程就得以退出阻塞的状态。更确切的说,如果线程被Object.wait, Thread.join和Thread.sleep三种方法之一阻塞,那么,它将接收到一个中断异常(InterruptedException),从而提早地终结被阻塞状态.如果线程没有被阻塞,这时调用interrupt()将不起作用;仅仅是设置中断标志位为true
同时注意下面三个方法的区别:
publicvoid interrupt()
public static boolean interrupted():线程的中断状态由该方法清除
public boolean isInterrupted() :测试线程是否已经中断。线程的中断状态不受该方法的影响。
总结:
t.interrupt()不会中断正在执行的线程,只是将线程的标志位设置成true。但是如果线程在调用sleep(),join(),wait()方法时线程被中断,则这些方法会抛出InterruptedException,在catch块中捕获到这个异常时,线程的中断标志位已经被设置成false了,因此在此catch块中调用t.isInterrupted(),Thread.interrupted()始终都为false,
而t.isInterrupted与Thread.interrupted()的区别是API中已经说明很明显了,Thread.interrupted()假如当前的中断标志为true,则调完后会将中断标志位设置成false ,而t.isInterrupted对标志位不做任何处理
假如我们有一个任务如下,交给一个Java线程来执行,如何才能保证调用interrupt()来中断它呢?
Java代码
class ATask implements Runnable{
private double d = 0.0;
public void run() {
//死循环执行打印"I am running!" 和做消耗时间的浮点计算
while (true) {
System.out.println("I am running!");
for (int i = 0; i < 900000; i++) {
d = d + (Math.PI + Math.E) / d;
}
//给线程调度器可以切换到其它进程的信号
Thread.yield();
}
}
}
public class InterruptTaskTest {
public static void main(String[] args) throws Exception{
//将任务交给一个线程执行
Thread t = new Thread(new ATask());
t.start();
//运行一断时间中断线程
Thread.sleep(100);
System.out.println("****************************");
System.out.println("Interrupted Thread!");
System.out.println("****************************");
t.interrupt();
}
}
运行这个程序,我们发现调用interrupt()后,程序仍在运行,如果不强制结束,程序将一直运行下去,如下所示:
Java代码
......
I am running!
I am running!
I am running!
I am running!
****************************
Interrupted Thread!
****************************
I am running!
I am running!
I am running!
I am running!
I am running!
....
虽然中断发生了,但线程仍然在进行,离开线程有两种常用的方法:
抛出InterruptedException和用Thread.interrupted()检查是否发生中断,下面分别看一下这两种方法:
1.在阻塞操作时如Thread.sleep()时被中断会抛出InterruptedException(注意,进行不能中断的IO操作而阻塞和要获得对象的锁调用对象的synchronized方法而阻塞时不会抛出InterruptedException)
Java代码
class ATask implements Runnable{
private double d = 0.0;
public void run() {
//死循环执行打印"I am running!" 和做消耗时间的浮点计算
try {
while (true) {
System.out.println("I am running!");
for (int i = 0; i < 900000; i++) {
d = d + (Math.PI + Math.E) / d;
}
//休眠一断时间,中断时会抛出InterruptedException
Thread.sleep(50);
}
} catch (InterruptedException e) {
System.out.println("ATask.run() interrupted!");
}
}
}
程序运行结果如下:
Java代码
I am running!
I am running!
****************************
Interrupted Thread!
****************************
ATask.run() interrupted!
可以看到中断任务时让任务抛出InterruptedException来离开任务.
2.Thread.interrupted()检查是否发生中断.Thread.interrupted()能告诉你线程是否发生中断,并将清除中断状态标记,所以程序不会两次通知你线程发生了中断.
Java代码
class ATask implements Runnable{
private double d = 0.0;
public void run() {
//检查程序是否发生中断
while (!Thread.interrupted()) {
System.out.println("I am running!");
for (int i = 0; i < 900000; i++) {
d = d + (Math.PI + Math.E) / d;
}
}
System.out.println("ATask.run() interrupted!");
}
}
程序运行结果如下:
Java代码
I am running!
I am running!
I am running!
I am running!
I am running!
I am running!
I am running!
****************************
Interrupted Thread!
****************************
ATask.run() interrupted!
相关文章推荐
- android thread Interrupte使用方法
- 多线程之Thread.interrupt()方法使用
- 对Thread.interrupt()方法很详细的介绍
- interrupt()、interrupted()方法的使用和线程退出的时机
- Thread.interrupt()方法很详细的介绍
- Thread.interrupt方法
- CWinThread的使用方法
- Thread中带参方法无法使用之解决方案
- Activity中runOnUiThread方法的使用
- activity的runOnUiThread方法使用
- CWinThread的使用方法
- 为何java里的Thread类的方法suspend()和resume()不推荐使用?
- CWinThread的使用方法
- Android 开发中的 Handler ,Thread ,Message ,Runnable 的综合使用方法
- Android 开发中的 Handler ,Thread ,Message ,Runnable 的综合使用方法
- boost::thread使用方法
- Thread类中的join方法的使用
- Thread的join方法使用解析
- 控制反转与java thread使用方法
- 在MFC中使用AFXBEGINTHREAD的方法