声明

该系列文章由书籍《Netty权威指南》第二版整理而来。只为记录学习笔记。
若认为内容侵权请及时通知本人删除相关内容。

[TOC]

时间服务器–升级版(线程池)的BIO

服务端代码

服务端主程序

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
public class TimeServer {
public static void main(String[] args) {
int port = 1234;
ServerSocket server = null;
try {
server = new ServerSocket(port);
System.out.println("The time server is listening in port : " + port);
Socket socket = null;
// 线程池
ClientHandlerPool singleExecutor = new ClientHandlerPool(50, 10000);
while (true) {
socket = server.accept();
singleExecutor.execute(new TimeServerHandler(socket));
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (server != null) {
try {
server.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}

服务端线程池

1
2
3
4
5
6
7
8
9
10
11
12
13
public class ClientHandlerPool {
private ExecutorService executor;
public ClientHandlerPool(int maxPoolSize, int queueSize) {
executor = new ThreadPoolExecutor(Runtime.getRuntime().availableProcessors(), maxPoolSize, 120L,
TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(queueSize));
}
public void execute(Runnable task) {
executor.execute(task);
}
}

服务端处理器类

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
46
public class TimeServerHandler implements Runnable {
private Socket socket;
private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
public TimeServerHandler(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
BufferedReader in = null;
PrintWriter out = null;
try {
in = new BufferedReader(new InputStreamReader(this.socket.getInputStream()));
out = new PrintWriter(this.socket.getOutputStream(), true);
String body = null;
while (true) {
body = in.readLine();
if (body == null)
break;
out.println(this.sdf.format(new Date()));
}
} catch (Exception e) {
if (in != null) {
try {
in.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
if (out != null) {
out.close();
out = null;
}
if (this.socket != null) {
try {
this.socket.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}
}

客户端代码

客户端代码和上一篇文章“传统BIO”一致。

总结

这种升级版BIO模型有如下特点:

  • 服务端资源开销可控
  • 当服务端队列积满后,新的连接必须排队
  • 可能导致所有的新的连接都超时

参考资料: 《Netty权威指南》第二版