专注于快乐的事情

线程中断

线程中断总结

背景

有些时候,需要一个线程死掉, 或者让它结束某种等待的状态,该怎么办呢?
比较安全的做法是:
1.使用等待/通知机制
2.给那个线程一个中断信号, 让它自己决定该怎么办

线程中断使用场景:

场景1: 在某个子线程中为了等待一些特定条件的到来, 你调用了Thread.sleep(10000), 预期线程睡10秒之后自己醒来, 但是如果这个特定条件提前到来的话, 来通知一个处于Sleep的线程。

场景2: 线程通过调用子线程的join方法阻塞自己以等待子线程结束, 但是子线程运行过程中发现自己没办法在短时间内结束, 于是它需要想办法告诉主线程别等我了. 这些情况下, 就需要中断。

中断不是终止程序,程序需要终止由程序自己决定。

Interrupted的经典代码

1
2
3
4
5
6
7
8
9
10
11
12
13
public void run(){
try{
....
while(!Thread.currentThread().isInterrupted()&& more work to do){
// do more work;
}
}catch(InterruptedException e){
// thread was interrupted during sleep or wait
}
finally{
// cleanup, if required
}
}

线程中断相关接口

Thread.interrupt

Thread.interrupt()将线程中断状态设置为true,表明此线程目前是中断状态。此时如果调用isInterrupted方法,将会得到true的结果。
interrupt方法本质上不会进行线程的终止操作的,它不过是改变了线程的中断状态。

Thread.interrupted

检测当前线程是否已经中断,此方法会清除中断状态。

假设当前线程中断状态为true,第一次调此方法,将返回true,表明的确已经中断了,同时将中断状态重新置为false。

第二次调用后,将会返回false。

Thread.isInterrupte

检测调用该方法的对象所表示的线程是否已经中断,与上一方法的区别在于此方法不会清除中断状态。

如果进行中断,对于非阻塞中的线程, 只是改变了中断状态,此时通过Thread.isInterrupted()将返回true。
对于阻塞状态中的线程,Thread.sleep(), Object.wait(), Thread.join(), 这个线程收到中断信号后, 会抛出InterruptedException, 当前线程的中断状态重新被置为false

一个例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
class InterruptTest extends Thread {

volatile boolean stop = false;

public static void main(String args[]) throws Exception {
InterruptTest thread = new InterruptTest();

System.out.println("Starting thread...");
thread.start();

Thread.sleep(3000);

System.out.println("Asking thread to stop...");


thread.stop = true;


thread.interrupt();

Thread.sleep(3000);
System.out.println("Stopping application...");
System.exit(0);
}

public void run() {
while (!stop) {
System.out.println("Thread running...");
try {
Thread.sleep(50000);
} catch (InterruptedException e) {
// 接收到一个中断异常(InterruptedException),从而提早地终结被阻塞状态
System.out.println("Thread interrupted...");
}
}

System.out.println("Thread exiting under request...");
}
}

在这个例子中,thread.stop = true; 但此时线程阻塞,run方法不被执行。不能进行检查stop。
语句后调用thread.interrupt()方法, 该方法将在线程阻塞时抛出一个中断。
信号,该信号将被catch语句捕获到,一旦捕获到这个信号,线程就提前终结自己的阻塞状态,这
样,它就能够 再次运行run方法了,然后检查到stop = true,while终止。

当代码调用中须要抛出一个InterruptedException, 你可以选择把中断状态复位, 也可以选择向外抛出InterruptedException, 由调用者来决定。

评论系统未开启,无法评论!