Servlet3.0如何实现异步请求

2025-11-13 15:09:27

1、在Servlet3.0之前,Servlet才采用Thread-Per——Request的方式处理请求。即每一次http请求都由一个线程从头到尾负责处理。

如果一个请求需要进行IO操作,比如访问数据库,调用第三方服务接口等,那么其所对应的线程将同步地等待IO操作完成,而IO操作是非常慢的,所以此时的线程并不能及时的释放回线程池以供后续使用,在并发量越来越大的情况下,这将带来严重的新能问题。即便像Spring、struts这样的高层框架也脱离不了这样的问题,因为他们都是建立在Servlet之上的。为了解决这样的问题,Servlet3.0引入了一步处理,然后在Servlet3.1中又引入了非阻塞IO来进行增加一步处理的性能。

Servlet3.0如何实现异步请求

2、实现异步请求需要使用AsynContext对象。新建一个实现异步请求的Servlet。

package com.gwolf;

import java.io.IOException;

import javax.servlet.ServletException;

import javax.servlet.annotation.WebServlet;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

@WebServlet(value="/async")

public class HelloAsyncServlet extends HttpServlet{

        @Override

        protected void doGet(HttpServletRequest req, HttpServletResponse resp) 

                        throws ServletException, IOException {

                

        }

        

        public void sayHello() throws Exception {

                System.out.println(Thread.currentThread()+ "processing.....");

                Thread.sleep(3000);

        }

        

}

Servlet3.0如何实现异步请求

3、如果要支持异步请求,需要在WebServlet注解中开启异步支持。

@WebServlet(value="async",asyncSupported=true)

Servlet3.0如何实现异步请求

4、接下来就是开启异步模式,进行业务逻辑异步处理。

package com.gwolf;

import java.io.IOException;

import javax.servlet.AsyncContext;

import javax.servlet.ServletException;

import javax.servlet.ServletResponse;

import javax.servlet.annotation.WebServlet;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

@WebServlet(value="/async",asyncSupported=true)

public class HelloAsyncServlet extends HttpServlet{

        @Override

        protected void doGet(HttpServletRequest req, HttpServletResponse resp) 

                        throws ServletException, IOException {

                System.out.println("主线程开始。。。。" + Thread.currentThread());

                AsyncContext async =  req.startAsync();

                

                async.start(new Runnable() {

                        

                        @Override

                        public void run() {

                                try {

                                        System.out.println("副线程开始。。。。" + Thread.currentThread());

                                        sayHello();

                                        async.complete();

                                        ServletResponse response =  async.getResponse();

                                        response.getWriter().write("hello async...");

                                        System.out.println("副线程结束。。。。" + Thread.currentThread());

                                } catch (Exception e) {

                                        e.printStackTrace();

                                }

                        }

                });

                

                System.out.println("主线程结束。。。。" + Thread.currentThread());

        }

        

        public void sayHello() throws Exception {

                System.out.println(Thread.currentThread()+ "processing.....");

                Thread.sleep(3000);

        }

        

}

Servlet3.0如何实现异步请求

5、运行应用,查看主线程和异步线程的执行情况。

Servlet3.0如何实现异步请求

6、这样异步请求就不会占用主线程池的线程,从而影响程序的性能。

Servlet3.0如何实现异步请求

声明:本网站引用、摘录或转载内容仅供网站访问者交流或参考,不代表本站立场,如存在版权或非法内容,请联系站长删除,联系邮箱:site.kefu@qq.com。
猜你喜欢