【图解Java多线程设计模式】Two-Phase Termination模式

先执行完终止处理再终止线程。

k3qJ9U.png

该模式的要点如下:

  • 安全地终止线程(安全性)
  • 必定会进行终止处理(生存性)
  • 发出终止请求后尽快进行终止处理(响应性)

示例

首先会启动一个线程,该线程每隔约500毫秒进行一次计数。接着,在大约10秒后程序就会终止该线程。

类图

k3qODs.png

时序图

k3j3qJ.png

CountupThread.java

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
public class CountupThread extends Thread {
private long counter = 0;
private volatile boolean shutdownRequested = false;

public void shutdownRequest() {
shutdownRequested = true;
interrupt();
}

public boolean isShutdownRequested() {
return shutdownRequested;
}

@Override
public void run() {
try {
while (!isShutdownRequested()) {
doWork();
}
} catch (InterruptedException e) {
} finally {
doShutdown();
}
}

private void doWork() throws InterruptedException {
counter++;
System.out.println("doWork: counter = " + counter);
Thread.sleep(500);
}

private void doShutdown() {
System.out.println("doShutdown: counter = " + counter);
}
}

Main.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class Main {

public static void main(String[] args) {
System.out.println("main: BEGIN");

try {
CountupThread t = new CountupThread();
t.start();

Thread.sleep(10000);

System.out.println("main: shutdownRequest");
t.shutdownRequest();

System.out.println("main: join");
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}

System.out.println("main: END");
}
}

运行结果

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
main: BEGIN
doWork: counter = 1
doWork: counter = 2
doWork: counter = 3
doWork: counter = 4
doWork: counter = 5
doWork: counter = 6
doWork: counter = 7
doWork: counter = 8
doWork: counter = 9
doWork: counter = 10
doWork: counter = 11
doWork: counter = 12
doWork: counter = 13
doWork: counter = 14
doWork: counter = 15
doWork: counter = 16
doWork: counter = 17
doWork: counter = 18
doWork: counter = 19
doWork: counter = 20
main: shutdownRequest
main: join
doShutdown: counter = 20
main: END

登场角色

TerminationRequester(终止请求发出者)

TerminationRequester角色负责向Terminator角色发出终止请求。在示例程序中,由Main类扮演此角色。

Terminator(终止者)

Terminator角色负责接收终止请求,并实际执行终止处理。它提供了表示终止请求的shutdownRequest方法。shutdownRequest方法不需要使用Single Threaded Execution模式。
当shutdownRequest方法被调用后,Terminator角色会在考虑了安全性的基础上,自己进入“终止处理中”状态。接着当终止处理结束后,Terminator角色就会终止自己。
Terminator角色带有一个表示自己是否已经接收到终止请求的标志,在需要安全地开始终止处理时,会检查这个标志。如果能够频繁地检查该标志,就可以缩短接收到终止请求后变为“终止处理中”状态所需的时间。
在示例程序中,由CountupThread类扮演此角色。

类图

k3vFW6.png