如何正确的终止线程
线程终止的方法往往是运行完成、或者异常终止。但是如何正确的让线程T1优雅终止线程T2呢?
我们的JAVA提供线程的interrupt方法用来通知如何停掉线程,但是在实现上要注意以下问题
- interrupt会导致线程的wait和sleep抛出InterruptedException,在处理完该异常时候interrupt会被重置为false
- 第三方包有可能未正确处理interrupt,所以最佳实践是我们要自己处理线程停止标记位也就是下面的stop
也不能只依赖标记位,因为很可能这时候线程处于wait或者block状态,所以应该标记位+interrupt方法一起
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
40public class StopThread {
private Thread work;
private boolean stop = false;
private AtomicBoolean lock = new AtomicBoolean(false);
public void startJob() {
if (lock.get()) {
return;
}
lock.compareAndSet(false, true);
work = new Thread(() -> {
while (!stop) {
System.out.println("======job run!!!====");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
//重置中断标记位
Thread.currentThread().interrupt();
}
}
//释放锁
lock.compareAndSet(true, false);
System.out.println("======job stop====");
});
work.start();
}
public void stopJob() {
//方式单纯的interrupt没有被正确处理,所以标志位置为终止
stop = true;
//防止线程睡眠
work.interrupt();
}
}