前言
上篇文章中,实现了浏览器与服务器之间的通信,但是是单线程下的通信,效率低下。这篇文章,通过线程池来实现多线程通信。但TomCat除了具有线程池外,还具有一个任务队列来存储没来得及处理的请求,我暂时不会像TomCat一样让线程池从任务队列中获取请求,而是一个固定的线程池,有请求就去处理。
代码实现
我们创建个线程池类
public class TomCatThreadPool {
ExecutorService executor = null;
//线程数量
int coreNum;
public TomCatThreadPool(int coreNum) {
System.out.println("初始化TomCat的线程池");
this.coreNum = coreNum;
executor = Executors.newFixedThreadPool(coreNum);
}
public void execute(Socket socket) {
executor.execute(()->{
System.out.println(Thread.currentThread().getName()+"开始处理请求");
InputStream inputStream = null;
try {
inputStream = socket.getInputStream();
//设置编码为UTF-8,并以字符的形式读取
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
String msg = null;
//循环读取
while ((msg = bufferedReader.readLine()) != null) {
if (msg.length() == 0) {
break;
}
//讲读取的信息打印在控制台上
System.out.println(msg);
}
//读取完毕后,进行一个简单响应
OutputStream outputStream = socket.getOutputStream();
String responseHead = "HTTP/1.1 200\r\n" +
"Content-Type: text/html;charset=utf-8\r\n\r\n";
String responseBody = "这是一个简单的展示页面";
String response = responseHead + responseBody;
//将数据展示给浏览器
outputStream.write(response.getBytes());
outputStream.close();
inputStream.close();
socket.close();
System.out.println("断开连接...");
} catch (IOException e) {
e.printStackTrace();
}
});
}
}
该线程池类,里面存在一个固定线程池,线程池中的线程数量由主程序决定,线程池中的线程用来处理请求而不是主线程处理,将第一节中的大部分代码粘到线程池中执行。
那么主程序中就变成如下代码
public static void main(String[] args) {
TomCatThreadPool threadPool = new TomCatThreadPool(2);
try {
//监听8080端口
ServerSocket serverSocket = new ServerSocket(8080);
System.out.println("我的服务器启动成功...");
//socket没接收到关闭事件之前不退出循环
while (!serverSocket.isClosed()) {
System.out.println("等待连接...");
//等待连接,该事件会阻塞线程
Socket socket = serverSocket.accept();
System.out.println("连接成功...");
threadPool.execute(socket);
}
} catch (IOException e) {
e.printStackTrace();
System.out.println("服务器启动失败");
}
}
测试
访问8080端口,可以看到线程池中的线程去处理请求。而不是主线程

至此实现了多线程通信。
本文介绍了如何使用Java的ExecutorService和固定线程池在TomCat风格下实现多线程的HTTP通信,通过创建TomCatThreadPool类,处理来自客户端的Socket请求,避免了单线程的低效问题。
478





