实现异步有哪些方法

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

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

方式一: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);
    }

方式二:使用消息队列

依赖

 
            com.rabbitmq
            amqp-client
            4.2.0
        
        
            org.springframework.amqp
            spring-rabbit
            1.7.6.RELEASE
        

调用场景:

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());
        /**
         * 自定义的类型:
* 1,注册完成; * 2:登录成功;
* 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

依赖


            org.quartz-scheduler
            quartz
            2.3.0
        

调用方式:

 @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

你可能感兴趣的:(实现异步有哪些方法)