既然我们使得一个线程开始运行,那如果没有异常情况,线程将会一直运行直到代码执行完毕。当然,如果我们在线程运行中途想去终止此线程,也是有方法的。
通常我们使用interrup方法接下来,为大家引入这个方法的使用:
1.isInterrupted()、interrupted()方法的使用
- 对于每一个线程,都会有一个Boolean类型中断标志位,该标志位默认false,表示没有被中断我们可以调用线程的
isInterrupted()
方法来查看当前的中断标志位的状态,该标志位不影响线程的状态。
- 另外,还有一个类似的方法
interrupted()
也是可以检查当前线程是否中断,但在调用该方法后,如果标志位为true,该方法会将标志位重置为false。
现在,我们通过代码来演示二者的差别:
public class InterruptThread {
public static void main(String[] args) {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
boolean a = Thread.interrupted();
boolean b = Thread.currentThread().isInterrupted();
//表示创建后初始标志位是false,表示没有被中断
System.out.println(b);
}
}
});
thread.start();
}
}
在这个代码中,主要工作就是创建了一个线程,让这个线程循环十次打印出标志位的状态。
当我们没有对线程进行中断时,a、b均会分别默认打印出10个false,这就证明在没中断线程时,默认标志位为false
接下来,对线程进行中断操作:
public class InterruptThread {
public static void main(String[] args) {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
boolean a = Thread.interrupted();
boolean b = Thread.currentThread().isInterrupted();
//表示创建后初始标志位是false,表示没有被中断
System.out.println(b);
}
}
});
thread.start();
thread.interrupt();
}
}
此时,我们加入了堆线程的中断操作后,再次分别调用interrupted()和isInterrupted()方法。此时,前者将会打印出1个true和9个false,而后者会打印出10个true。
这就证实了我们上面提到过的,使用interrupted()这个静态方法,会返回当前的标志位并且将标志位重置为true,而使用isInterrupted()这个实例方法就仅仅返沪这个标志位的状态而不会更改其值。
2.interrupt()方法
- 使用interrupt可以中断一个线程
- 如果线程调用了 wait/join/sleep 等方法而阻塞挂起,则以 InterruptedException 异常的形式通知,清除
中断标志
同样,代码演示:
public class InterruptThread {
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().isInterrupted());
}
try {
//调用sleep()/wait()/join()方法时,线程进入阻塞状态,
// 此时也可以进行中断,中断后抛出异常,抛出后重置标志位为false
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().isInterrupted());
}
}
});
thread.start();
thread.interrupt();
}
}
上述代码中,我们创建了一个线程,在这个线程中循环输出五次标志位的状态。在抛出异常后,再次输出五次标志位状态。
运行代码得到如下结果:
这意味着,在执行了interrupt方法后,确实将线程的中断标志位置为true,但由于线程此时调用了sleep方法使得线程超时等待状态,这时就抛出一个异常。在抛出异常后,标志位就被重置为false,所以再次打印标志位就变为false。
所以,我们使用interrupt方法的优势是可以中断阻塞线程
3.总结
方法 | 说明 |
---|---|
public void interrupt() | 中断对象关联,如果线程正在阻塞,则以异常形式通知,否则设置标志位 |
public static boolean interrupted() | 判断当前线程的中断标志位是否设置,调用后清除标志位 |
public boolean isInterrupted() | 判断当前线程的中断标志位是否设置,调用后不清除标志位 |