程序分为两部分,一部分是功能操作,一部分为结束操作(释放资源)。
Two-phase Termination直译的话是“两相终止”,不过就这个模式而言,该译作“两阶段终止”比较适当,想像您有一个执行程序正在周期性的运作,在“运作阶段”您送出了停止执行程序的请求,这时候执行程序不该慌张的马上终止目前的工作,而是先完成这一次周期的工作,然后进入“善后阶段”完成一些善后的工作,例如关闭档案或网路串流,所谓的两阶段终止,即中止“运作阶段”,并完成“善后阶段”,完整的完成执行绪的工作。
public class AppServer extends Thread{
private boolean start = true;
private static final int DEFAULT_PORT = 13345;
private int port ;
private final ExecutorService executor = Executors.newFixedThreadPool(10);
private ServerSocket server;
private List<SocketClient> clients = new ArrayList<>();
public AppServer() {
this(DEFAULT_PORT);
}
public AppServer(int port){
this.port = port;
}
@Override
public void run() {
try {
server = new ServerSocket(port);
while (start){
Socket socket = server.accept();
SocketClient client = new SocketClient(socket);
executor.execute(client);
clients.add(client);
}
}catch (IOException e){
e.printStackTrace();
shutdown();
}
}
public void shutdown(){
if(!start){
return;
}
start = false;
try {
server.close();
} catch (IOException e) {
e.printStackTrace();
}
clients.stream().forEach(SocketClient::close);
executor.shutdown();
}
}
public class SocketClient implements Runnable{
private final Socket client;
private boolean running = true;
public SocketClient(Socket client) {
if (client == null){
throw new RuntimeException("client is null !!! Please check the socket");
}
this.client = client;
}
@Override
public void run() {
try (
InputStream inputStream = client.getInputStream();
OutputStream outputStream = client.getOutputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
PrintWriter writer = new PrintWriter(outputStream)
){
while (running){
String message = reader.readLine();
if("quit".equals(message)){
running = false;
break;
}
System.out.println("come from client " + message);
writer.println("echo " + message);
writer.flush();
}
}catch (IOException e){
e.printStackTrace();
}
}
public void close(){
if(!running){
return;
}
running = false;
try {
client.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public class Client {
public static void main(String[] args){
AppServer server = new AppServer();
server.start();
try {
Thread.sleep(15_000);
server.shutdown();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}