使用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();
}
}
本作品採用《CC 協議》,轉載必須註明作者和本文連結