zoukankan      html  css  js  c++  java
  • 010 异步处理Rest服务

    一:任务

    1.任务

      使用Runnable异步处理Rest服务

      使用DefaultResult异步处理Rest服务

      异步处理的配置

    2.原理图说明

      

    二:Callable进行异步处理

    1.程序

      新建一个anysc的包

     1 package com.cao.web.async;
     2 
     3 import java.util.concurrent.Callable;
     4 
     5 import org.slf4j.Logger;
     6 import org.slf4j.LoggerFactory;
     7 import org.springframework.web.bind.annotation.RequestMapping;
     8 import org.springframework.web.bind.annotation.RestController;
     9 
    10 @RestController
    11 public class AsyncController {
    12     private Logger logger=LoggerFactory.getLogger(getClass());
    13     
    14     @RequestMapping("/order")
    15     public Callable<String> order() throws Exception {
    16         logger.info("主线程开始");
    17         //业务逻辑放在副线程中
    18         Callable<String> result=new Callable<String>() {
    19 
    20             @Override
    21             public String call() throws Exception {
    22                 logger.info("副线程开始");
    23                 Thread.sleep(5000);
    24                 logger.info("副线程返回");
    25                 return "success";
    26             }
    27             
    28         };
    29         
    30         logger.info("主线程返回");
    31         
    32         return result;
    33     }
    34 
    35 }

    2.效果

      重点关注时间

      

    三:使用DeferredResult

    1.问题

      方式一是有问题的,因为副线程是需要主线程调用起来的。

      是写在主线程中的。

      有些场景是不合适的。

      线程间使用DeferredResult沟通起来。

    2.场景如下:

      

    3.程序

      程序太多,有点复杂

      控制器

     1 package com.cao.web.async;
     2 
     3 import java.util.concurrent.Callable;
     4 
     5 import org.apache.commons.lang.RandomStringUtils;
     6 import org.slf4j.Logger;
     7 import org.slf4j.LoggerFactory;
     8 import org.springframework.beans.factory.annotation.Autowired;
     9 import org.springframework.web.bind.annotation.RequestMapping;
    10 import org.springframework.web.bind.annotation.RestController;
    11 import org.springframework.web.context.request.async.DeferredResult;
    12 
    13 @RestController
    14 public class AsyncController {
    15     private Logger logger=LoggerFactory.getLogger(getClass());
    16     @Autowired
    17     private Queue queue;
    18     
    19     @Autowired
    20     private DeferredResultHolder deferredResultHolder;
    21     
    22     /**
    23      * 主要是验证Callable
    24      * @return
    25      * @throws Exception
    26      */
    27     @RequestMapping("/order")
    28     public Callable<String> order() throws Exception {
    29         logger.info("主线程开始");
    30         //业务逻辑放在副线程中
    31         Callable<String> result=new Callable<String>() {
    32 
    33             @Override
    34             public String call() throws Exception {
    35                 logger.info("副线程开始");
    36                 Thread.sleep(5000);
    37                 logger.info("副线程返回");
    38                 return "success";
    39             }
    40             
    41         };
    42         
    43         logger.info("主线程返回");
    44         
    45         return result;
    46     }
    47     /**
    48      * 主要是验证
    49      * @return
    50      * @throws Exception
    51      */
    52     @RequestMapping("/newOrder")
    53     public DeferredResult<String> newOrder() throws Exception {
    54         logger.info("主线程开始");
    55         //
    56         String oderNumber=RandomStringUtils.randomNumeric(8);
    57         queue.setPlaceOrder(oderNumber);
    58         DeferredResult<String> result=new DeferredResult<>(); 
    59         deferredResultHolder.getMap().put(oderNumber, result);
    60         logger.info("主线程返回");
    61         
    62         return result;
    63     }
    64 
    65 }

      queue.java

     1 package com.cao.web.async;
     2 
     3 import org.slf4j.Logger;
     4 import org.slf4j.LoggerFactory;
     5 import org.springframework.stereotype.Component;
     6 
     7 @Component
     8 public class Queue {
     9     private String placeOrder;
    10     private String completeOrder;
    11     
    12     private Logger logger=LoggerFactory.getLogger(getClass());
    13     
    14     public String getPlaceOrder() {
    15         return placeOrder;
    16     }
    17     public void setPlaceOrder(String placeOrder) throws Exception {
    18         new Thread(() -> {
    19             logger.info("接到下单请求");
    20             try {
    21                 Thread.sleep(2000);
    22             } catch (InterruptedException e) {
    23                 e.printStackTrace();
    24             }
    25             // 表示处理完成,应用2将结果返回给了completeOrder
    26             this.completeOrder = placeOrder;
    27             logger.info("下单请求处理完毕" + placeOrder);
    28         }
    29 
    30         ).start();
    31         
    32     }
    33     public String getCompleteOrder() {
    34         return completeOrder;
    35     }
    36     public void setCompleteOrder(String completeOrder) {
    37         this.completeOrder = completeOrder;
    38     }
    39     
    40 }

      deferredResultHolder.java

     1 package com.cao.web.async;
     2 
     3 import java.util.HashMap;
     4 import java.util.Map;
     5 
     6 import org.springframework.stereotype.Component;
     7 import org.springframework.web.context.request.async.DeferredResult;
     8 
     9 @Component
    10 public class DeferredResultHolder {
    11     //一个是订单号,一个是订单号的处理结果
    12     private Map<String,DeferredResult<String>> map=new HashMap<>();
    13     public Map<String,DeferredResult<String>> getMap(){
    14         return map;
    15     }
    16     public void setMap(Map<String,DeferredResult<String>> map) {
    17         this.map=map;
    18     }
    19 }

      QueueListener.java

     1 package com.cao.web.async;
     2 
     3 import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.log;
     4 
     5 import org.apache.commons.lang.StringUtils;
     6 import org.slf4j.Logger;
     7 import org.slf4j.LoggerFactory;
     8 import org.springframework.beans.factory.annotation.Autowired;
     9 import org.springframework.context.ApplicationListener;
    10 import org.springframework.context.event.ContextRefreshedEvent;
    11 import org.springframework.stereotype.Component;
    12 
    13 @Component
    14 public class QueueListener implements ApplicationListener<ContextRefreshedEvent>{
    15     @Autowired
    16     private Queue queue;
    17     
    18     @Autowired
    19     private DeferredResultHolder deferredResultHolder;
    20     
    21     private Logger logger=LoggerFactory.getLogger(getClass());
    22 
    23     @Override
    24     public void onApplicationEvent(ContextRefreshedEvent event) {
    25         new Thread(() -> {
    26             while (true) {
    27                 if (StringUtils.isNotBlank(queue.getCompleteOrder())) {
    28                     String orderNumber = queue.getCompleteOrder();
    29                     logger.info("返回订单处理结果" + orderNumber);
    30                     deferredResultHolder.getMap().get(orderNumber).setResult("place order success");
    31                     queue.setCompleteOrder(null);
    32                 } else {
    33                     try {
    34                         Thread.sleep(100);
    35                     } catch (InterruptedException e) {
    36                         // TODO Auto-generated catch block
    37                         e.printStackTrace();
    38                     }
    39                 }
    40             }
    41         }).start();
    42         
    43         
    44     }
    45     
    46     
    47 }

      

    4.效果

      前端效果

      

      控制台效果

      

    三:异步线程的配置

    1.说明

      对于拦截器,与同步的拦截器不一样,仍然需要配置、

    2.主要配置

      

  • 相关阅读:
    每周必写
    每周必写
    每周必写
    感想及阅读内容
    阅读内容及感想
    每周感想和阅读内容
    每周感想及阅读内容
    每周感想及阅读内容
    分答
    每周感想及阅读内容
  • 原文地址:https://www.cnblogs.com/juncaoit/p/9733768.html
Copyright © 2011-2022 走看看