实现异步有哪些方法

有哪些方法可以实现异步呢?

方式一:java 线程池

示例:

@Test
    public final void test_ThreadPool() throws InterruptedException {
        ScheduledThreadPoolExecutor scheduledThreadPoolExecutor=new ScheduledThreadPoolExecutor(2);

        scheduledThreadPoolExecutor.schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println("两秒之后执行 :" );
            }
        }, 2, TimeUnit.SECONDS);
        Thread.sleep(3000);
    }

方式二:使用消息队列

依赖

 <dependency>
            <groupId>com.rabbitmq</groupId>
            <artifactId>amqp-client</artifactId>
            <version>4.2.0</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.amqp</groupId>
            <artifactId>spring-rabbit</artifactId>
            <version>1.7.6.RELEASE</version>
        </dependency>

调用场景:

if (null != increaseLevel && increaseLevel) {
                //只要考试通过,则升级经纪人级别,对应字段"level"
                this.agentDao.increasByOne(userId, "level");

                int msgType = 4;//参考RabbitMessageInfo 中type的含义
                Map map = new HashMap();
                map.put("userId", userId);
                //                map.put()
                rmqProducerService.sendRabbitMessage(msgType, map);
            }

消息推送的Service:

@Component
public class RmqProducerService {
    protected static Logger logger = Logger.getLogger(RmqProducerService.class);
        @Resource(name = "rmqProducer")
    private IRmqProducer producer;

    public void sendRabbitMessage(int msgType, Object map) {
        sendRabbitMessage(msgType, map, -1);
    }

    /***
     *
     * @param msgType
     * @param map
     * @param delaySecond : -1:不延迟;不传值默认为5,单位:秒
     */
    public void sendRabbitMessage(int msgType, Object map, Integer delaySecond) {
        try {
            producer = (IRmqProducer) SpringMVCUtil.getBean("rmqProducer");
            if (null == producer) {
                logger.info("没有设置推送 rmqProducer");
                return;
            }
            //通过消息队列,提示用户成功升级
            RabbitMessageInfo rabbitMessageInfo = new RabbitMessageInfo(msgType);

            rabbitMessageInfo.setValue(map);
            this.producer.sendMessage(rabbitMessageInfo.toJson(), delaySecond);
        } catch (Exception e) {
            e.printStackTrace();
            logger.error(e.getMessage(), e);
        }
    }
}

IRmqProducer的实现

@Component
public class RmqProducer implements IRmqProducer {
    protected static final Logger logger = Logger.getLogger(RmqProducer.class);
    private RabbitTemplate template;
    @Value("${rabbit.routingkey}")
    private String routingKey;
    @Value("${rabbit.DirectExchange}")
    private String exchange;

    public RmqProducer() {

    }
    @Autowired
    public RmqProducer(RabbitTemplate template) {
        this.template = template;
    }


    /***
     *
     * @param content
     * @param delaySecond : -1:不延迟;不传值默认为5,单位:秒
     */
    public void sendMessage(String content, Integer delaySecond) {
        if (exchange.equals(routingKey)) {
            logger.error("exchange 和routingKey相同,请确认配置是否有误");
        }
        MessageProperties properties = getDelayMessageProperties(delaySecond);

        try {
            MessageBuilder messageBuilder = MessageBuilder.withBody(content.getBytes(SystemHWUtil.CHARSET_UTF));
            if (null != properties) {
                messageBuilder.andProperties(properties);
            }
            template.send(exchange, routingKey,
                    messageBuilder.build());
//            template.convertAndSend(exchange, routingKey, content, correlationId);
        } catch (Exception e) {
            e.printStackTrace();
            logger.error(e.getMessage(), e);
        }
    }

    /***
     *
     * @param delaySecond :  -1:不延迟;不传值默认为5,单位:秒
     * @return
     */
    public static MessageProperties getDelayMessageProperties(Integer delaySecond) {
        MessageProperties properties = null;
        boolean delaySecondNull = (delaySecond == null);
        if (null == delaySecond) {
            delaySecond = 5;
        }
        if (delaySecondNull || ((!delaySecondNull) && -1 != delaySecond)) {
            properties = new MessageProperties();
            properties.setDelay(1000 * delaySecond);
        }
        return properties;
    }

    @Override
    public void confirm(CorrelationData correlationData, boolean ack, String s) {
        System.out.println(" 回调id:" + correlationData + "ack:" + ack);
    }

消息的消费方

@Component("queueListenter")
public class QueueConsumerListenter extends QueueListenter {
    @Resource
    private EventBus eventBus;
    @Resource
    private SMSService smsService;
    @Override
    public void onMessageArrived(Message message, Channel channel) {
        byte[] body = message.getBody();
        if (ValueWidget.isNullOrEmpty(body)) {
            return;
        }
        String msgBody = new String(body); //{"type":"7","value":"{\"mobile\":\"18701670126\",\"smsCode\":\"ccc\"}"}
        RabbitMessageInfo rabbitMessageInfo = RabbitMessageUtil.extractRabbitMessageInfo(msgBody);
        System.out.println("receive time : " + TimeHWUtil.getCurrentFormattedTime());
        System.out.println("send time : " + rabbitMessageInfo.getCurr_time());
        System.out.println("receive msg : " + msgBody);
        System.out.println("receive type : " + rabbitMessageInfo.getType());
        /**
         * 自定义的类型:<br />
         * 1,注册完成;
         * 2:登录成功;<br />
         * 3:考试通过;
         * 4:升级成功;
         * 5,换绑手机号;
         * 7:发送短信
         */
        int type = Integer.parseInt(rabbitMessageInfo.getType());
        switch (type) {
            case 2://登录成功
                LoginSucessRabbitMessageInfo loginSucessRabbitMessageInfo = (LoginSucessRabbitMessageInfo) HWJacksonUtils.deSerialize(msgBody, LoginSucessRabbitMessageInfo.class);
                LoginSuccessLog loginSuccessLog = loginSucessRabbitMessageInfo.getValue();
                eventBus.post(loginSuccessLog);
                break;
            case 7:
                //发送短信
                SendSmsRabbitMessageDto sendSmsRabbitMessageInfoDto = null;
                SMSRabbitMessageValue smsRabbitMessageInfo = null;
                try {
                    sendSmsRabbitMessageInfoDto = (SendSmsRabbitMessageDto) HWJacksonUtils.deSerialize(msgBody, SendSmsRabbitMessageDto.class);
                } catch (Exception e) {
                    e.printStackTrace();
                    SendSmsRabbitMessageStrDto sendSmsRabbitMessageStrDto = (SendSmsRabbitMessageStrDto) HWJacksonUtils.deSerialize(msgBody, SendSmsRabbitMessageStrDto.class);
                    smsRabbitMessageInfo = (SMSRabbitMessageValue) HWJacksonUtils.deSerialize(sendSmsRabbitMessageStrDto.getValue(), SMSRabbitMessageValue.class);
                }

                if (null != sendSmsRabbitMessageInfoDto) {
                    smsRabbitMessageInfo = sendSmsRabbitMessageInfoDto.getValue();
                }

                if (null != smsRabbitMessageInfo) {
                    if (!ValueWidget.isNumeric(smsRabbitMessageInfo.getSmsCode())) {
                        LogicBusinessException.throwException("1001", "内容必须是数值");
                    }
                    smsService.sendSMSByCode(smsRabbitMessageInfo.getMobile(), smsRabbitMessageInfo.getSmsCode());
                }
        }
    }

}

方式三:使用定时器

使用注解: @Scheduled

依赖

<dependency>
            <groupId>org.quartz-scheduler</groupId>
            <artifactId>quartz</artifactId>
            <version>2.3.0</version>
        </dependency>

调用方式:

 @Scheduled(cron = "0 0 */4 * * ?")//每4小时执行一次
    public void updatePerOneHour() {
	}

 /***
     * 每天凌晨的1点半自动执行
     */
    @Scheduled(cron = "* 30 1 * * ?")
    public void updateUserOrderStatisticsAllCount() {
        //更新所有用户的UserOrderStatistics(未支付订单的总数, 待评价数量,申请退单/退款/售后的数量)
        this.customerService.updateAllUserOrderStatistics();

        //删除 houseInfo 不存在的购房订单
        this.purchaseHouseOrderDao.deleteDirtyData();
    }


方式四:guava 的 AsyncEventBus

参考:
https://google.github.io/guava/releases/17.0/api/docs/com/google/common/eventbus/AsyncEventBus.html

转载于:https://my.oschina.net/huangweiindex/blog/1858505

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值