关于Java异步处理方法请求问题

工作中,或多或少都会用到多线程处理问题。今日就遇到一个问题来作为经验留存,内容稍作简单,见解较浅,欢迎留言补充

问题:用户发单之后,发送多条邮件通知

用户在请求一个发单接口之后,需要发送多条邮件通知给目标人。

发单成功返回给客户端一条成功通知:{"code":0,"message":"ok"}

理想状态下是:请求发单成功 ——> 客户端即刻收到成功通知(不必等待邮件发送)

一般邮件发送需要占用一定的时间,导致不能及时吧成功的消息发回给客户端,影响体验。所以需要在发送邮件的方法中,加入异步处理流程。

实现

框架:SpringMVC

一开始,我在发送邮件方法上,加上注解@Async,发现在controller中调用,没有效果

public class SendEmailHelper {

    private static Logger logger = Logger.getLogger(SendEmailHelper.class);

    @Async
    public static void send(String title, List<String> toList, String content) {

        SendEmailHead head = new SendEmailHead("firefly", "212faef1");
        SendEmailBody body = new SendEmailBody();
        body.setModel(new SendEmailModel(title, content));
        body.setTemplateName("legalNewOrder");
        body.setTitle(title);
        body.setToList(toList);

        try {
            XStream xStreamJ = new XStream(new JsonHierarchicalStreamDriver() {
                public HierarchicalStreamWriter createWriter(Writer out) {
                    return new JsonWriter(out, JsonWriter.DROP_ROOT_MODE);
                }
            });

            String json = xStreamJ.toXML(new SendEmailData(head, body));
            logger.info("请求邮件发送数据:" + json);

            Thread.sleep(10000);    // 模拟时间

            logger.info("发送邮件完成");
        } catch (Exception e) {
            logger.error("法务发单邮件发送失败:" + e.getMessage());
        }
    }

}

后来查询一些文档, 目前找到两种解决方案,问题解决

注意:以下代码建议使用第一种方案,spring自动维护线程池,第二种方案是每次都会新建一个线程,若想要使用第二种,最好创建一个线程管理来维护线程池来配合使用。

第一种:新建一个线程运行

public class SendEmailHelper {

    private static Logger logger = Logger.getLogger(SendEmailHelper.class);
    
    public static void send(String title, List<String> toList, String content) {

        // 新建线程
        new Thread() {
            public void run() {
                SendEmailHead head = new SendEmailHead("firefly", "212faef1");
                SendEmailBody body = new SendEmailBody();
                body.setModel(new SendEmailModel(title, content));
                body.setTemplateName("legalNewOrder");
                body.setTitle(title);
                body.setToList(toList);

                try {
                    XStream xStreamJ = new XStream(new JsonHierarchicalStreamDriver() {
                        public HierarchicalStreamWriter createWriter(Writer out) {
                            return new JsonWriter(out, JsonWriter.DROP_ROOT_MODE);
                        }
                    });

                    String json = xStreamJ.toXML(new SendEmailData(head, body));
                    logger.info("请求邮件发送数据:" + json);

                    Thread.sleep(10000);  // 模拟请求时间

                    logger.info("发送邮件完成");
                } catch (Exception e) {
                    logger.error("法务发单邮件发送失败:" + e.getMessage());
                }
            }
        }.start();
    }

}

第二种方法:使用注解 @Async

把SendEmailHelper,改造成Service,然后使用注解@Async

XML配置

<bean id="sendEmailService" class="com.wusong.firefly.push.message.email.service.impl.SendEmailServiceImpl">

</bean>

java配置

public interface SendEmailService {
    void send(String title, List<String> toList, String content);
}

// 实现类
public class SendEmailServiceImpl implements SendEmailService{
    private static Logger logger = Logger.getLogger(SendEmailServiceImpl.class);

    @Override
    @Async
    public void send(String title, List<String> toList, String content) {
        SendEmailHead head = new SendEmailHead("firefly", "212faef1");
        SendEmailBody body = new SendEmailBody();
        body.setModel(new SendEmailModel(title, content));
        body.setTemplateName("legalNewOrder");
        body.setTitle(title);
        body.setToList(toList);

        try {
            XStream xStreamJ = new XStream(new JsonHierarchicalStreamDriver() {
                public HierarchicalStreamWriter createWriter(Writer out) {
                    return new JsonWriter(out, JsonWriter.DROP_ROOT_MODE);
                }
            });

            String json = xStreamJ.toXML(new SendEmailData(head, body));
            logger.info("请求邮件发送数据:" + json);
            
            Thread.sleep(10000);  // 模拟请求时间
                    
            logger.info("发送邮件完成");
        } catch (Exception e) {
            logger.error("法务发单邮件发送失败:" + e.getMessage());
        }
    }
}


赞(52) 打赏
未经允许不得转载:优客志 » JAVA开发
分享到:

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏