Spring Boot如何使用多线程

Spring Boot如何使用多线程

业务场景

假设我们需要做一个设备实时监控的程序, 有如下业务需求:

  1. 在系统启动时, 根据设备个数生成对应的线程
  2. 线程内部轮询, 实现设备的初始化和状态监控

本文重点介绍如何在Spring Boot中使用多线程, 后续会加更使用状态模式实现设备在不同状态下的各种操作

方案

先来列举下面试经常会问的问题, Java中有几种实现线程的方式:

  • 继承Thread类
  • 实现Runnable接口
  • 使用Callable和FutureTask
  • 使用线程池
  • Spring Boot中的@Async

本文着重讲述如何最后一种, 其实Spring Boot也是集前几者之大成

在这里多说一句, 很多新人小伙伴们经常会在写代码之前不好好调研

比如知道了可以用线程池, 就火急火燎的写了一个自己的实现类, 但伴随着开发深入, 设计到线程的管理/守护线程等就会出现很多预料之外的问题

所以推荐各位和我一样处理学习期的兄弟们, 先确定自己的技术栈(例如MyBatis还是JPA), 之后在技术栈的基础上去搜索有无相关的工具/实现/轮子, 写代码之前一定要思考代码

Spring Boot的多线程就是最好的例子, 起码在笔者看来, 它很优雅且完美

开启多线程

第一步, 在启动类增加@EnableAsync注解:

@EnableAsync
public class DeviceApplication {
  /**
   * main方法
   *
   * @param args 参数
   */
  public static void main(String[] args) {
    SpringApplication.run(DeviceApplication.class, args);
  }

}
复制代码

第二步, 在需要多线程处理的类或方法上增加@Async注解:

public class ConnectorService {

    private static final int INTERVAL = 5000;
    
    /**
   * 设备链接方法
   *
   * @param device 设备实体
   */
  @Async
  public void connect(Device device) {
    device.setState(new OffLineState(device));
    try {
      while (true) {
        device.getState().heartBeat();
        Thread.sleep(INTERVAL);
      }
    } catch (InterruptedException e) {
      LOGGER.error(String.format("设备[%s]监控线程意外中断", device.getId()), e);
      Thread.currentThread().interrupt();
    }
  }
    
}
复制代码

如此这般, 在使用默认配置的情况下, 我们就实现了connect方法的多线程处理, 每次对connect方法的调用都会启动新的线程

具体的配置参数网上一搜一大堆, 不再赘述

需要注意的坑

@Async注解和事务一样, 在类内部调用会出现注解失效的情况, 需要格外注意

原创文章,作者:睿达君,如若转载,请注明出处:https://zrrd.net.cn/1548.html

发表回复

登录后才能评论
咨询电话
联系电话:0451-81320577

地址:哈尔滨市松北区中小企业总部基地13F

微信咨询
微信咨询
QQ咨询
分享本页
返回顶部