您的位置:首页 > 其它

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!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: