zoukankan      html  css  js  c++  java
  • 异步并发实战

    13.1 同步阻塞调用

    13.2 异步Future

    private void FutureTest() {
        //请求
        Future<?> userInfoTask = POOL.submit(() -> {/**请求客户信息**/});
        Future<?> orderInfoTask = POOL.submit(() -> {/**请求订单数据**/});
    
        try {
            Object userInfo = userInfoTask.get(300, TimeUnit.MILLISECONDS);
            Object orderInfo = orderInfoTask.get(300, TimeUnit.MILLISECONDS);
        } catch (Exception e) {
            if (userInfoTask != null) {
                userInfoTask.cancel(true);
            }
            if (orderInfoTask != null) {
                orderInfoTask.cancel(true);
            }
            throw new RuntimeException(e);
        }
    }

    13.3 异步Callback

    13.4 异步编排CompletableFuture

       CompletableFuture可以对多个异步处理进行编排,实现更复杂的异步处理。内部使用ForkJoinPool实现异步处理。ForkJoinPool内部使用双端队列实现工作密取。

    13.5 异步Web服务实现

    AsyncContext示例:

    当Tomcat封装请求和响应传递给Servlet,Servlet通常要阻塞等待业务处理完毕才能返回。使用startAsync开启异步,自己则继续处理下一个请求,后续的处理由AsyncContext完成,并返回客户端。对于客户端来说,依然是同步等待,但是对于Tomcat来说,是异步处理请求的。

    @Service
    public class AsyncContextTest {
    
        @Autowired
        private HttpServletRequest request;
    
        private static final ExecutorService POOL = Executors.newCachedThreadPool();
    
        public void test() {
            //释放servlet线程让其继续接待其他请求
            AsyncContext asyncContext = request.startAsync();
            //先不设置超时自己控制
            asyncContext.setTimeout(0);
    
            POOL.submit(() -> {
                try {
                    //模拟处理过程
                    Thread.sleep(1000);
                    //返回客户端
                    PrintWriter writer = asyncContext.getResponse().getWriter();
                    writer.println("handle success");
                    //任务执行完成,通知回调
                    asyncContext.complete();
                } catch (Exception ignore) {
                    //
                }
            });
        }
    }

     结合CompletableFuture

    public void test2(Callable<CompletableFuture> task) throws Exception {
        final String uri = request.getRequestURI();
        final Map<String, String[]> params = request.getParameterMap();
        //释放Servlet
        AsyncContext asyncContext = request.startAsync();
        asyncContext.getRequest().setAttribute("uri", uri);
        asyncContext.getRequest().setAttribute("params", params);
        asyncContext.setTimeout(5000);
    
        //执行任务
        CompletableFuture call = task.call();
        //执行完成后
        call.thenAccept(result -> {
            //返回调用方
            HttpServletResponse httpServletResponse = (HttpServletResponse) asyncContext.getResponse();
            try {
                byte[] bytes;
                if (result instanceof String) {
                    bytes = ((String) result).getBytes("GBK");
                } else {
                    bytes = JSON.toJSONBytes(result);
                }
                httpServletResponse.setContentType("text/html;charset=gbk");
                httpServletResponse.setContentLength(bytes.length);
                httpServletResponse.getOutputStream().write(bytes);
            } catch (Exception e) {
                httpServletResponse.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
                System.out.println(e.getMessage());
            } finally {
                asyncContext.complete();
            }
        }).exceptionally(exception -> {
            //异常处理
            asyncContext.complete();
            return null;
        });
    
    }

      

    13.6 请求缓存

      一次请求中重复调用同一个接口。譬如一次用户查询,调用多次商品详情接口。一般的解决方法是对商品详情查询接口包装一层缓存。另这一种可行的方法是使用Hystrix提供的HystrixRequestContext

      注意一下HystrixCommand

    13.7 请求合并

      CompletableFuture需要事先定义好多个任务,而Hystrix支持将多个单请求合并成一个批量请求。

      注意一下HystrixCollapser

    人生就像蒲公英,看似自由,其实身不由己。
  • 相关阅读:
    .TTableRegionMapper' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    Cannot resolve com.google.zxing:javase:unknown
    为什么需要权限管理?
    spring boot 上传文件出错:org.springframework.web.multipart.MultipartException: Could not parse multipart s
    如何在windows上设置文件的默认打开方式
    如何将vscode设置为中文
    使用hutool工具类进行简单的excel导入和导出的工具类
    上传照片到本地服务器上(亲测有效)
    Centos 防火墙
    VirtualBox 安装增强工具
  • 原文地址:https://www.cnblogs.com/walker993/p/14702251.html
Copyright © 2011-2022 走看看