对于正在执行,和正在阻塞的线程,如果需要中断(或者stop),可以采用以下几种方式,
- 对要停止的线程,使用stop()方法,
- 对要停止的线程,使用interrupt()方法
对于,stop()方法已经废弃,因为涉及到资源未回收等安全问题,
阻塞线程的中断
使得线程阻塞的方法,sleep(), wait()等,对于这些阻塞方法,会强制使用try catch包围,捕获, InterruptedException。
try {
Thread.sleep(100); // 休眠100ms
} catch (InterruptedException ie) {
}
因此,当我们阻塞的线程调用interrupt()方法后,会对线程设置中断标记,阻塞的地方,会识别中断标记,并抛出InterruptedException,后,清除中断标记 !!!。此时此刻,调用isInterrupted()方法,会得到false。
try {
Thread.sleep(900); // 休眠900ms,多等一会,让main线程中断他
} catch (InterruptedException ie) {
System.out.println(isInterrupted());
System.out.println(Thread.currentThread().getName() +" ("+this.getState()+") catch InterruptedException.");
}
//main函数
Thread t1 = new Demo1("t1"); // 新建“线程t1”
System.out.println(t1.getName() +" ("+t1.getState()+") is new.");
t1.start(); // 启动“线程t1”
System.out.println(t1.getName() +" ("+t1.getState()+") is started.");
// 主线程休眠300ms,然后主线程给t1发“中断”指令。
Thread.sleep(300);
t1.interrupt();
System.out.println(t1.getName() +" ("+t1.getState()+") is interrupted.");
// 主线程休眠300ms,然后查看t1的状态。
Thread.sleep(300);
System.out.println(t1.getName() +" ("+t1.getState()+") is interrupted now.");
//输出结果
t1 (NEW) is new.
t1 (RUNNABLE) is started.
t1 (TIMED_WAITING) is interrupted. //sleep()中断时线程状态
false//被中断后,异常捕获,清空中断状态,变成false
t1 (RUNNABLE) catch InterruptedException.
t1 (TERMINATED) is interrupted now.
运行中线程的中断
运行中的线程,即没有被阻塞,也是通过interrupt()方法对线程进行中断,此时,线程被的中断标记被设置为true,通过isInterrupted()可以获得true,通常如法做法,
通过中断标志
@Override
public void run() {
int i=0;
while(!isInterrupted()) {
++i;
System.out.println(Thread.currentThread().getName()+" "+i+" "+isInterrupted());
}
System.out.println(Thread.currentThread().getName()+" "+i+" "+isInterrupted());
}
//main函数
Thread t1 = new Demo1("t1"); // 新建“线程t1”
System.out.println(t1.getName() +" ("+t1.getState()+") is new.");
t1.start(); // 启动“线程t1”
System.out.println(t1.getName() +" ("+t1.getState()+") is started.");
// 主线程短暂休息。
Thread.sleep(1);
t1.interrupt();
System.out.println(t1.getName() +" ("+t1.getState()+") is interrupted.");
// 主线程休眠300ms,然后查看t1的状态。
Thread.sleep(300);
System.out.println(t1.getName() +" ("+t1.getState()+") is interrupted now.");
//输出结果
t1 (NEW) is new.
t1 (RUNNABLE) is started.
t1 1 false
t1 2 false
....
t1 31 false
t1 (RUNNABLE) is interrupted.
t1 31 true //发现了true
t1 (TERMINATED) is interrupted now.
通过标记变量
通过其他变量,来进行判断,如果设置为false,则跳出循环
private volatile boolean flag= true;
protected void stopTask() {
flag = false;
}
@Override
public void run() {
while (flag) {
// 执行任务...
}
}
线程的中断通常设置方法
一个线程运行过程中,有阻塞的时候,也有运行的时候,阻塞的时候中断,需要记住中断标记在异常捕获后会清楚 。代码如下
@Override
public void run() {
try {
// 1. isInterrupted()保证,只要中断标记为true就终止线程。
while (!isInterrupted()) {
// 执行任务...
}
} catch (InterruptedException ie) {
// 2. InterruptedException异常保证,当InterruptedException异常产生时,线程被终止。
}
}
当然,可以通过设置变量来替换掉!isInterrupted()
效果。
网友评论