首先梳理一下大致流程
客户端发送请求 -> tomcat分配一个线程处理请求 -> 找到对应的注册的Servlet执行 -> 获得输出流返回。
核心线程池,通过ThreadPoolExecutor创建一个线程池,选择阻塞的有界队列 ArrayBlokingQueue,防止资源耗尽。通过创建ServerSocket,监听再拿到一个Socket,交给异步的CompletableFuture 进行处理。
private void runServer() {
ServerSocket serverSocket = null;
ThreadPoolExecutor requestPool = null;
ArrayBlockingQueue<Runnable> runnableQueue = new ArrayBlockingQueue<>(150);
try {
serverSocket = new ServerSocket(PORT, 100);
requestPool = new ThreadPoolExecutor(
100
, 600
, 3000
, TimeUnit.MILLISECONDS
, runnableQueue
, CitrusThreadFactory.getFactoryOne()
, new ThreadPoolExecutor.AbortPolicy()
);
printSystemInfo();
} catch (IOException e) {
e.printStackTrace();
}
if (serverSocket != null) {
while (!serverSocket.isClosed()) {
Socket socket = null;
try {
socket = serverSocket.accept();
CompletableFuture.runAsync(new ServerService(socket), requestPool);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
自定义一个ThreadFactory,用于自定义线程的名称,方便查看。
private static final AtomicInteger POOL_NUMBER = new AtomicInteger(1);
private final ThreadGroup group;
private final AtomicInteger threadNumber = new AtomicInteger(1);
private final String namePrefix;
CitrusThreadFactory() {
SecurityManager s = System.getSecurityManager();
group = (s != null) ? s.getThreadGroup() :
Thread.currentThread().getThreadGroup();
namePrefix = "Servlet核心请求线程池: " +
POOL_NUMBER.getAndIncrement() +
" :请求线程 :";
}
@Override
public Thread newThread(Runnable r) {
Thread t = new Thread(group, r,
namePrefix + threadNumber.getAndIncrement(),
0);
if (t.isDaemon()) {
t.setDaemon(false);
}
if (t.getPriority() != Thread.NORM_PRIORITY) {
t.setPriority(Thread.NORM_PRIORITY);
}
return t;
}
public static ThreadFactory getFactoryOne(){
return new CitrusThreadFactory();
}
……
在serverService再对请求进行处理,通过拿到 输入输出流,解析http协议内容,再通过指定输入流返回指定协议格式的数据即可。