Spring Boot笔记—多线程系列(一)—使用多线程

1 使用场景

​ 在Spring Boot项目中,有时候需要单独监控某一个业务,或者需要在主流程之外单独处理一些数据。

​ 在Spring项目中,由于Bean 对象是spring容器管理的,直接new出来的对象是没法使用bean里面依赖的其他组件,如dao,mapper等。此时,如果想使用bean里依赖的其他组件,则需要spring的多线程。

此篇文章,只是介绍了使用spring多线程的简单方式。至于多线程的参数设置,自定义线程池等将在另外的文章详解。

2 实现方式

2.1 使用Spring封装的异步

2.1.1 介绍

Spring Boot开启异步,需要两个注解:@EnableAsync和@Async。

  • @EnableAsync

    在配置类中通过添加该注解,开启对异步任务的支持。

  • @Async

    在实际执行的bean的方法中使用该注解表名这是一个异步任务。

2.1.2 样例

2.1.2.1 目录结构
Study
├── src
│   ├── main
│   │   ├── java
│   │   │   └── top
│   │   │       └── yxdz
│   │   │           └── study
│   │   │               ├── StudyApplication.java
│   │   │               └── spring
│   │   │                   └── springboot
│   │   │                       └── thread
│   │   │                           └── service
│   │   │                               ├── ITestService.java
│   │   │                               └── impl
│   │   │                                   └── TestSerivceImpl.java
│   └── test
│       └── java
│           └── top
│               └── yxdz
│                   └── study
│                       └── StudyApplicationTests.java
2.1.2.2 代码
  • StudyApplicationTests——测试入口

    这是测试类,也是配置类,添加了注解@EnableAsync,用来在此测试中启用异步。

    package top.yxdz.study;
    
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.scheduling.annotation.EnableAsync;
    import org.springframework.test.context.junit4.SpringRunner;
    import top.yxdz.study.spring.springboot.thread.service.ITestService;
    
    @RunWith(SpringRunner.class)
    @SpringBootTest
    @EnableAsync
    public class StudyApplicationTests {
    
        @Autowired
        ITestService iTestService;
    
        @Test
        public void contextLoads() {
    
            for(int i=0; i<5; i++){
                iTestService.method1("Async" + i);
            }
    
            try {
                //等待10s,防止异步代码被强制关闭导致线程抛出异常
                Thread.sleep(10000);
            }catch (InterruptedException e){
                e.printStackTrace();
            }
        }
    }
  • ITestService——测试类接口

    package top.yxdz.study.spring.springboot.thread.service;
    
    public interface ITestService {
    
        /**
         * 异步测试
         * @param msg
         */
        void method1(String msg);
    }
  • TestSerivceImpl——测试类实现

    这是实现类,在实现函数上添加了注释@Async表示异步调用。

    import org.slf4j.LoggerFactory;
    import org.springframework.scheduling.annotation.Async;
    import org.springframework.stereotype.Service;
    import top.yxdz.study.spring.springboot.thread.service.ITestService;
    
    import java.time.LocalDateTime;
    
    
    @Service("TestSerivceImpl")
    public class TestSerivceImpl implements ITestService {
    
        private static Logger LOG = LoggerFactory.getLogger(TestSerivceImpl.class);
    
        @Override
        @Async
        public void method1(String msg){
    
            try {
                LOG.info(LocalDateTime.now().toString() + msg);
                Thread.sleep(1000);
                LOG.info(LocalDateTime.now().toString() + msg);
            }catch (InterruptedException e){
                e.printStackTrace();
            }
        }
    }
2.1.2.3 执行结果
  • 执行结果

    2018-12-12 20:07:37.631  INFO 34428 --- [         task-5] t.y.s.s.s.t.s.impl.TestSerivceImpl       : 2018-12-12T20:07:37.631Async4
    2018-12-12 20:07:37.631  INFO 34428 --- [         task-1] t.y.s.s.s.t.s.impl.TestSerivceImpl       : 2018-12-12T20:07:37.631Async0
    2018-12-12 20:07:37.631  INFO 34428 --- [         task-4] t.y.s.s.s.t.s.impl.TestSerivceImpl       : 2018-12-12T20:07:37.631Async3
    2018-12-12 20:07:37.631  INFO 34428 --- [         task-2] t.y.s.s.s.t.s.impl.TestSerivceImpl       : 2018-12-12T20:07:37.631Async1
    2018-12-12 20:07:37.631  INFO 34428 --- [         task-3] t.y.s.s.s.t.s.impl.TestSerivceImpl       : 2018-12-12T20:07:37.631Async2
    2018-12-12 20:07:38.635  INFO 34428 --- [         task-4] t.y.s.s.s.t.s.impl.TestSerivceImpl       : 2018-12-12T20:07:38.635Async3
    2018-12-12 20:07:38.635  INFO 34428 --- [         task-2] t.y.s.s.s.t.s.impl.TestSerivceImpl       : 2018-12-12T20:07:38.635Async1
    2018-12-12 20:07:38.635  INFO 34428 --- [         task-3] t.y.s.s.s.t.s.impl.TestSerivceImpl       : 2018-12-12T20:07:38.635Async2
    2018-12-12 20:07:38.635  INFO 34428 --- [         task-1] t.y.s.s.s.t.s.impl.TestSerivceImpl       : 2018-12-12T20:07:38.635Async0
    2018-12-12 20:07:38.635  INFO 34428 --- [         task-5] t.y.s.s.s.t.s.impl.TestSerivceImpl       : 2018-12-12T20:07:38.635Async4
  • 结果说明

    该方式使用的是异步,执行iTestService.method1("Async" + i);时,会开一个线程执行,并不会影响主线程的运行,for循环会毫无障碍(不会受Thread.sleep(1000)的影响)运行完毕,同时也会产生四个线程,独立运行method1方法。

    因为是四个线程独立运行的结果,所以结果的顺序并不能保证每次一致。

转载于:https://www.cnblogs.com/yxdz2018/p/10117611.html

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值