【SpringBoot】测试单元使用多线程

本文讲述了在SpringBoot学习中遇到的乐观锁问题,如何在单元测试中使用CountDownLatch确保多线程按照预期顺序执行,避免主线程结束导致的并发问题。作者通过实例展示了CountDownLatch的await()和countDown()方法在解决此类问题中的应用。
摘要由CSDN通过智能技术生成

       📝个人主页:五敷有你      


 🔥系列专栏:SpringBoot
 

⛺️稳重求进,晒太阳

问题产生

今天学习了乐观锁,但在测试单元执行多线程的时候出现了问题,多线程并没有直接结果

在控制台没有任何输出结果。开始搜索问题

答案:

单元测试是不支持多线程的,因为当主线程结束以后,无论子线程结束与否,都会强制退出程序,主线程优先级最高,所以解决办法是先让子线程执行完,然后结束主线程,可以利用CountDown计数器来处理。

CountDown

概念

CountDownLatch可以使一个获多个线程等待其他线程各自执行完毕后再执行。

CountDownLatch 定义了一个计数器,和一个阻塞队列, 当计数器的值递减为0之前,阻塞队列里面的线程处于挂起状态,当计数器递减到0时会唤醒阻塞队列所有线程,这里的计数器是一个标志,可以表示一个任务一个线程,也可以表示一个倒计时器,CountDownLatch可以解决那些一个或者多个线程在执行之前必须依赖于某些必要的前提业务先执行的场景。

CountDownLatch 常用方法说明

  • CountDownLatch(int count); //构造方法,创建一个值为count 的计数器。 ​
  • await();//阻塞当前线程,将当前线程加入阻塞队列。 ​
  • await(long timeout, TimeUnit unit);//在timeout的时间之内阻塞当前线程,时间一过则当前线程可以执行, ​
  • countDown();//对计数器进行递减1操作,当计数器递减至0时,当前线程会去唤醒阻塞队列里的所有线程。

测试代码 

    CountDownLatch count=new CountDownLatch(3);
    @Resource
    UserMapper userMapper; 
@Test
    void contextLoads() throws InterruptedException {
        new Thread(()->{
            UpdateWrapper<User> wrapper1=new UpdateWrapper();
            wrapper1.set("name","John").eq("id",3);
            int update1 = userMapper.update(null, wrapper1);
            System.out.println("影响的行数"+update1);
            count.countDown();
        }).start();
        new Thread(()->{
            UpdateWrapper<User> wrapper2=new UpdateWrapper();
            wrapper2.set("name","jack").eq("id",3);
            int update2 = userMapper.update(null, wrapper2);
            System.out.println("影响的行数"+update2);
            count.countDown();
        }).start();
        new Thread(()->{
            UpdateWrapper<User> wrapper=new UpdateWrapper();
            wrapper.set("name","hu").eq("id",3);
            int update = userMapper.update(null, wrapper);
            System.out.println("影响的行数"+update);
            count.countDown();
        }).start();
        //count为0就被唤醒了
        count.await();


    }


3.正确实例,运行成功!!!

  • 16
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
Spring Boot提供了许多方便的方法来处理多线程事务。以下是一些常用的方法: 1. 声明式事务管理:使用Spring的@Transactional注解来管理事务,可以确保在方法执行过程中,如果出现异常,所有的操作都会回滚到最初的状态。 2. 编程式事务管理:使用Spring的TransactionTemplate来手动管理事务,可以在代码中指定何时开始和提交事务。 3. 分布式事务管理:使用Spring Boot集成的分布式事务管理框架,如Atomikos、Bitronix等,来处理跨多个数据库或消息队列的事务。 无论使用哪种方式,都需要在应用程序中配置数据源、事务管理器和事务通知器等相关组件。可以通过在application.properties文件中设置相关属性来完成配置。例如: spring.datasource.url=jdbc:mysql://localhost/mydb spring.datasource.username=username spring.datasource.password=password spring.datasource.driver-class-name=com.mysql.jdbc.Driver spring.datasource.tomcat.max-active=10 spring.datasource.tomcat.max-idle=5 spring.datasource.tomcat.min-idle=2 spring.datasource.tomcat.test-on-borrow=true spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect spring.jpa.hibernate.ddl-auto=create-drop spring.jpa.show-sql=true spring.transaction.default-timeout=30 spring.transaction.rollback-on-commit-failure=true 在这个配置文件中,我们定义了数据源、连接池、JPA配置和事务配置等相关属性。这些属性可以根据具体需求进行调整,以达到最佳的性能和可靠性。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

五敷有你

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值