美文网首页
学习笔记:Sevlet3异步 和 Spirng对Servlet3

学习笔记:Sevlet3异步 和 Spirng对Servlet3

作者: 瓢鳍小虾虎 | 来源:发表于2021-01-16 09:54 被阅读0次

使用异步机制处理请求是非常有用的,可以更好的利用cpu资源,提高程序吞吐量。因为通常的请求处理都是单线程的,请求线程是由tomcat分配的,如果业务处理要经过io操作等耗时较长的任务,线程就会一直被占用,tomcat线程池容易被占满,但是cpu并没有充分发挥效能。

Servlet3提供了对请求异步处理的机制。底层就是利用FutureTask的原理。Spirng框架也对Servlet3做了封装,从而更方便开发者使用。

import javax.servlet.AsyncContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

@WebServlet(value = "/servlet3/test", asyncSupported = true)
public class Servlet3Demo extends HttpServlet {
    private static ThreadPoolExecutor executor =
            new ThreadPoolExecutor(100, 200, 5000L, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<>(200));

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        AsyncContext asyncContext = req.getAsyncContext();

        // 记得使用线程池控制多线程操作。
        executor.execute(() ->{
            try {
                Thread.sleep(1000L); // 模拟业务
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            try {
                asyncContext.getResponse().getWriter().write("response string");
            } catch (IOException e) {
                e.printStackTrace();
            }
            asyncContext.complete();
        });

//        asyncContext.start(() -> {
//            try {
//                Thread.sleep(1000L); // 模拟业务
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            }
//
//            try {
//                asyncContext.getResponse().getWriter().write("response string");
//            } catch (IOException e) {
//                e.printStackTrace();
//            }
//            asyncContext.complete();
//        });
    }
}
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.async.DeferredResult;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

@RestController
public class SpringSevlet3ControllerDemo {
    private LinkedBlockingDeque<DeferredResult> quene = new LinkedBlockingDeque<>();
    ThreadPoolExecutor executor =
            new ThreadPoolExecutor(100, 200, 5000L, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<>(200));

    @GetMapping("/deferredresult/test")
    public DeferredResult<String> getSomeResult() {
        final DeferredResult<String> deferredResult = new DeferredResult<>(3000L); // 超时时间3秒

        quene.add(deferredResult);

        executor.submit(()->{
            try {
                Thread.sleep(1000L); // 模拟业务
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            String rs = "结果123";

            deferredResult.setResult(rs);
        });

        deferredResult.onTimeout(()->{
            // 超时业务代码
            String rs = "超时了";
            deferredResult.setResult(rs);
        });

        deferredResult.onCompletion(()->{
            // 完成后,移除quene队列
            quene.remove();
        });

        return deferredResult;
    }

    @Scheduled(fixedRate = 1000)
    public void scheduleResult(){ // 扫描队列
        for (int i = 0; i <quene.size() ; i++) {
            DeferredResult<String> stringDeferredResult = quene.poll();
            stringDeferredResult.setResult("result:"+i);
        }
    }
}

相关文章

  • 学习笔记:Sevlet3异步 和 Spirng对Servlet3

    使用异步机制处理请求是非常有用的,可以更好的利用cpu资源,提高程序吞吐量。因为通常的请求处理都是单线程的,请求线...

  • 构建消息推送系统之HTTP长连接实践

    前言 从Servlet3规范出来以后,利用Servlet3支持的异步特性,我们创建异步上下文asyncContex...

  • 异步处理

    异步处理 Servlet3 引入了一项新的特性,它可以让Servlet异步处理请求。 计算机的内存是有限的。Ser...

  • servlet3异步原理与实践

    一、什么是Servlet servlet 是基于 Java 的 Web 组件,由容器进行管理,来生成动态内容。像其...

  • 异步编程

    拉勾大前端的笔记,仅作为学习记录 内容概要 同步模式和异步模式 事件循环和消息队列 异步编程的几种方式 Promi...

  • Spring Event事件通知机制 源码学习

    笔记简述本学习笔记主要是介绍Spring中的事件通知是如何实现的,同步和异步事件通知的用法和实现细节以及Sprin...

  • 实现异步转同步

    极客时间-《Java并发编程实战》学习笔记 异步方法:调用方法,在方法中启动子线程异步调用:启动子线程调用方法异步...

  • Javascript学习笔记-异步和回调

    1. 异步 Javascript中程序是分块执行的,块的最常见单位是函数,在Javascript引擎执行的时候,通...

  • Bean和Spirng模块

    容纳Bean 在Spring中,应用对象生存于Spring容器中,如图所示,Spring容器可以创建、装载、配置这...

  • JavaScript Promises 学习笔记

    本文是 ECMAScript 2015 原生异步方法 Promise 的学习笔记。网上课程由 Udacity + ...

网友评论

      本文标题:学习笔记:Sevlet3异步 和 Spirng对Servlet3

      本文链接:https://www.haomeiwen.com/subject/iuwiaktx.html