弹簧引导中多线程开发的注意事项总结

  

  

Springt通过任务执行器(TaskExecutor)来实现多线程和并发编程。使用ThreadPoolTaskExecutor可实现一个基于线程池的TaskExecutor。而实际开发中任务一般是非阻碍的,即异步的,所以我们要在配置类中通过@EnableAsync开启对异步任务的支持,并通过实际执行Bean的方法中使用@Async注解来声明其是一个异步任务。

  

基于springboot的多线程程序开发过程中,由于本身也需要注入春容器进行管理,才能发挥springboot的优势,所以这篇文字主要用来记录开发中两者结合时需要注意的一些事项。

  

  

第一步我们把线程类的实例注入春容器进行管理

        @ configuration   @SpringBootApplication   @ import ({ThreadConfig.class})   公共类ThreadApp实现CommandLineRunner   {   公共静态void main (String [] args){抛出异常      ApplicationContext应用=SpringApplication.run (ThreadApp . class, args);//这里主要保存上下文对象实例,需要加上.SpringBootUtils类网上很多,可以自己搜下   SpringBootUtils.setApplicationContext(应用);      }//访问命令行参数   @Override   公共空间运行(字符串…args)抛出异常{//做某事   }   }//ComponentScan注解会扫描com.demo.thead下,也就是多线程类所在的包下的文件   @ configuration   @ComponentScan (basePackages={" com.demo.thread "})   公开课ThreadConfig {      }      

这里使用springboot @ import注解,把ThreadConfig里扫描到的包中带注解的示例,如@ component等注入到春容器当中。

  

<>强然后是线程的启动,这里在我的业务场景中有两种情况:

  

1,程序运行时,自动启动;

  

这在一般的可执行程序里面,当然可以直接在主函数里执行通过代码启动线程。但在springboot中,我们可以使用@PostConstruct注解的方式,让已经注入bean容器的线程对象自启动

        @ component   公开课demoThread延伸线   {//注意这里,如果你没有实现把多线程类的实例注入到春容器中,这里你是无法拿到其他自动装配的对象实例的的,这也是我们第一步的意义所在。   @ autowired   私人XxxService XxxService;      @PostConstruct   公共空间开始(){   super.start ();   }      公共空间run () {//好吧,在这里你就可以实现线程要实现的功能逻辑了,自然也可以直接使用装配好的服务对象实例。      }   }      

, 2,在程序中,需要开启线程时启动,比如在从卡夫卡接收数据,开启线程处理,当然这种情况下也需要通过第一步,把线程类实例注入到春容器中

        私人TaskThread线程;   私人ExecutorService taskPool=new ThreadPoolExecutor (   5,10,1000,   TimeUnit。毫秒,新的ArrayBlockingQueue<祝辞(10),   新的ThreadPoolExecutor.CallerRunsPolicy ());         @KafkaListener(主题=皒xTopic”)   公共空间接收(ConsumerRecord<对象,Object>consumerRecord) {   .toString JSONObject json=JSON.parseObject (consumerRecord.value () ());//通过SpringBootUtils获取线程类的实例   线程=SpringBootUtils.getBean (TaskThread.class);//启动线程//新线程(线程).start ();//向线程对象里传值   thread.init(我);//放入线程池执行   taskPool.execute(线程);      }         //注意这里是否添加@Scope(“原型”)注解   @ component   @Scope(“原型”)   公共类TaskThread实现Runnable {      受保护的int值=https://www.yisu.com/zixun/0;      @ autowired   私人XxxService XxxService;//ThreadLocal对象,单例模式下可以保证成员变量的线程安全和独立性。   公共ThreadLocal <整数> valueLocal=new ThreadLocal <整数> (){   @Override   保护整数initialValue () {   返回0;   }   };      保护静态最终记录器日志=LoggerFactory.getLogger (GpsTaskThread.class);      @Override   公众最终无效run () {   尝试{   LOG.info(价值+ " ");      }捕捉(异常e) {//TODO自动生成的catch块   e.printStackTrace ();   }   }      公共空间init (int值){   this.value=https://www.yisu.com/zixun/Value;   }   }      

在这里我们需要注意,TaskThread这个线程类在spirngboot中是否要添加<代码> @Scope(“原型”)注解设置为多例模式还是默认单例模式。

  

在单例模式下<代码> SpringBootUtils.getBean (TaskThread.class)

弹簧引导中多线程开发的注意事项总结