Servlet异步处理

背景

  在Servlet 3.0之前,Servlet采用Thread-Per-Request的方式处理请求,即每一次Http请求都由某一个线程从头到尾负责处理(同步处理)。如果一个请求需要进行IO操作,比如访问数据库、调用第三方服务接口等,那么其所对应的线程将同步地等待IO操作完成, 而IO操作是非常慢的,所以此时的线程并不能及时地释放回线程池以供后续使用,在并发量越来越大的情况下,这将带来严重的性能问题。为了解决这样的问题,Servlet 3.0引入了异步处理,然后在Servlet 3.1中又引入了非阻塞IO来进一步增强异步处理的性能。

异步处理

  在Servlet 3.0中,我们可以从HttpServletRequest对象中获得一个AsyncContext对象,该对象构成了异步处理的上下文,Request和Response对象都可从中获取。AsyncContext可以从当前线程传给另外的线程,并在新的线程中完成对请求的处理并返回结果给客户端,初始线程便可以还回给容器线程池以处理更多的请求。如此,通过将请求从一个线程传给另一个线程处理的过程便构成了Servlet 3.0中的异步处理。
这里写图片描述

示例代码

方式一:通过配置开启异步处理

<servlet> 
    <servlet-name>DemoServlet</servlet-name> 
    <servlet-class>footmark.servlet.Demo Servlet</servlet-class> 
    <async-supported>true</async-supported> 
</servlet>

方式二:通过注解开启异步处理
@WebServlet 或者 @WebFilter

@WebFilter(urlPatterns = "/demo",asyncSupported = true) 
public class DemoFilter implements Filter{...}

异步处理使用示例

import java.io.IOException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import javax.servlet.AsyncContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class AsynHttpServlet extends HttpServlet {

    private static final long serialVersionUID = 30000027129454057L;
    // 业务线程池
    private ExecutorService ex = Executors.newSingleThreadExecutor();

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 注意1:一定要由HTTP线程调用,否则离开后容器会立即发送响应;
        // 注意2:当前Servlet异步处理开关已经开启
        AsyncContext asyncContext = req.startAsync();
        // 注意1:超时时间不准,如果对时间敏感可以设为0,然后自己进行超时检查
        asyncContext.setTimeout(3000);
        // 提交给业务线程处理
        ex.execute(new AsynTask(asyncContext));
    }

    class AsynTask implements Runnable {
        AsyncContext asyncContext;

        AsynTask(AsyncContext asyncContext) {
            this.asyncContext = asyncContext;
        }

        @Override
        public void run() {
            try {
                // 业务处理
                asyncContext.complete();
            } catch (Exception e) {

            }

        }
    }
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值