在Java中没有办法立即停止1条线程,但是停止线程却显得尤其重要,如取消1个耗时操作。因此,Java提供了1种用于停止线程的机制——中断。
public void interrupt()
将调用者线程的中断状态设为true。
public boolean isInterrupted()
判断调用者线程的中断状态。
public static boolean interrupted
只能通过Thread.interrupted()调用。
它会做两步操作:
以下3个方法都是通过线程对象去调用。
suspend()
暂停调用者线程,只释放CPU履行权,不释放锁。
由于在不释放资源的情况下进入眠眠状态,容易产生死锁。因此已过时!
resume()
恢复调用者线程,让他处于就绪状态。
stop()
调用stop后,其实不会保证资源被正确地释放,它会使程序处于不正确的状态下。
PS:stop和interrupt的区分?
要使用中断,首先需要在可能会产生中断的线程中不断监听中断状态,1旦产生中断,就履行相应的中断处理代码。
当需要中断线程时,调用该线程对象的interrupt函数便可。
Thread t1 = new Thread( new Runnable(){
public void run(){
// 若未产生中断,就正常履行任务
while(!Thread.currentThread.isInterrupted()){
// 正常任务代码……
}
// 中断的处理代码……
doSomething();
}
} ).start();
正常的任务代码被封装在while循环中,每次履行完1遍任务代码就检查1下中断状态;1旦产生中断,则跳过while循环,直接履行后面的中断处理代码。
t1.interrupt();
上述代码履行后会将t1对象的中断状态设为true,此时t1线程的正常任务代码履行完成后,进入下1次while循环前Thread.currentThread.isInterrupted()的结果为true,此时退出循环,履行循环后面的中断处理代码。
stop函数停止线程过于暴力,它会立即停止线程,不给任何资源释放的余地,下面介绍两种安全停止线程的方法。
自定义1个同享的boolean类型变量,表示当前线程是不是需要中断。
volatile boolean interrupted = false;
Thread t1 = new Thread( new Runnable(){
public void run(){
while(!interrupted){
// 正常任务代码……
}
// 中断处理代码……
// 可以在这里进行资源的释放等操作……
}
} );
Thread t2 = new Thread( new Runnable(){
public void run(){
interrupted = true;
}
} );
中断标识
由线程对象提供,无需自己定义。
任务履行函数
Thread t1 = new Thread( new Runnable(){
public void run(){
while(!Thread.currentThread.isInterrupted()){
// 正常任务代码……
}
// 中断处理代码……
// 可以在这里进行资源的释放等操作……
}
} );
t1.interrupt();
上述两种方法本质1样,都是通过循环查看1个同享标记为来判断线程是不是需要中断,他们的区分在于:第1种方法的标识位是我们自己设定的,而第2种方法的标识位是Java提供的。除此以外,他们的实现方法是1样的。
上述两种方法之所以较为安全,是由于1条线程发出终止信号后,接收线程其实不会立即停止,而是将本次循环的任务履行完,再跳出循环停止线程。另外,程序员又可以在跳出循环后添加额外的代码进行扫尾工作。
上文都在介绍如何获得中断状态,那末当我们捕获到中断状态后,究竟如何处理呢?