使用 SpringBoot 框架
启动类需要加 @ServletComponentScan 注解

@WebServlet(urlPatterns = "/my/servlet", asyncSupported = true)
public class MyServlet extends HttpServlet implements InitializingBean {
    // 所有的请求都存放到这个队列里面
    private static LinkedBlockingQueue<AsyncContext> taskQueue = new LinkedBlockingQueue<>();

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 启动异步请求
        AsyncContext asyncContext = req.startAsync();
        try {
            // 将请求放入到队列里面
            taskQueue.put(asyncContext);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        // 开启一个线程从队列里面获取任务
        new Thread(()->{
            // 这里是一个死循环,不断的从队列里面获取任务
            while (true) {
                try {
                    // 从队列里面获取任务,如果队列为空,线程将会被阻塞,当队列不为空时,线程会被唤醒
                    AsyncContext asyncContext = taskQueue.take();
                    HttpServletResponse resp = (HttpServletResponse) asyncContext.getResponse();
                    asyncContext.start(()->{
                        System.out.println(Thread.currentThread() + "开始处理..." + LocalDateTime.now().toString());
                        try {
                            Thread.sleep(3000); // 睡眠三秒模型业务流程
                            resp.getWriter().println("Hello World:" + Thread.currentThread());
                        } catch (IOException | InterruptedException e) {
                            e.printStackTrace();
                        }
                        // 触发完成,相应用户
                        asyncContext.complete();
                        System.out.println(Thread.currentThread() + "处理结束..." + LocalDateTime.now().toString());
                    });
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }
}