0%

java | 设计模式 同步模式 两阶段终止模式

在一个线程 T1 中如何优雅的终止线程 T2,这里的优雅值得是 T2 有一个处理各种事务的机会。

  • 调用 stop()
    • stop 会真正的杀死线程,如果,线程锁住了共享资源,则被锁住后,就没办法释放
  • System.exit(int)
    • 会把整个程序退出
graph TB
    start(while)-->inputA[有没有被打断]
    inputA--yes-->inputB[料理后事]
    inputB-->inputC[结束循环]
    inputA--no-->inputD[睡眠2s]
    inputD--no error-->inputE[执行监控记录]
    inputD--error-->inputF[设置打断标记]
    inputE-->start
    inputF-->start

代码如下

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
40
41
42
43
44
45
package com.redisc;

import lombok.extern.slf4j.Slf4j;

@Slf4j(topic = "c.Test")
public class Test {

public static void main(String[] args) throws InterruptedException {
TwoPhaseTermination tpt = new TwoPhaseTermination();
tpt.start();

Thread.sleep(3000);
tpt.stop();
}
}

@Slf4j(topic = "c.TwoPhaseTermination")
class TwoPhaseTermination {
private Thread monitor;

public void start() {
monitor = new Thread(() -> {
while (true) {
Thread current = Thread.currentThread();
if (current.isInterrupted()) {
log.debug("料理后事");
break;
}
try {
Thread.sleep(1000);
log.debug("执行监控");// 如果睡眠过程中被打断,则会进入到下面的异常
} catch (InterruptedException e) {
e.printStackTrace();
// 重新设置打断标记,因为 sleep 打断的时候,会把打断标记设置为 false,所以,这里要重置一下
current.interrupt();
}
}
});
monitor.start();
}

public void stop() {
monitor.interrupt();
}
}

输出

1
2
3
4
5
6
7
23:06:58.965 [Thread-0] DEBUG c.TwoPhaseTermination - 执行监控
23:06:59.971 [Thread-0] DEBUG c.TwoPhaseTermination - 执行监控
java.lang.InterruptedException: sleep interrupted
at java.base/java.lang.Thread.sleep(Native Method)
at com.redisc.TwoPhaseTermination.lambda$start$0(Test.java:32)
at java.base/java.lang.Thread.run(Thread.java:832)
23:07:00.966 [Thread-0] DEBUG c.TwoPhaseTermination - 料理后事
请我喝杯咖啡吧~