让调用者自己干活的特殊线程池

让调用者自己干活的特殊线程池

1. 相关背景

单元测试时, 我们的某些业务代码可能是在线程池中运行的,可能会出现各种不一致的情况。

这时候可以hack一下, 创建一个调用者直接执行的线程池,避免干扰;

2. 实现代码



import java.util.concurrent.*;

// 让调用者自己执行的线程池
public class CallerRunsExecutor extends ThreadPoolExecutor {
    public CallerRunsExecutor() {
        super(0, 1, 0, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(1));
    }

    @Override
    public void execute(Runnable command) {
        command.run();
    }

    // 获取实例
    public static CallerRunsExecutor getInstance() {
        return new CallerRunsExecutor();
    }
}

3. SpringBoot配置实例

在 SpringBoot 对应的 @Configuration 配置中对Bean进行hack:


    // 是否是集成测试环境
    public static final AtomicBoolean itEnv = new AtomicBoolean(false);

    @Bean
    public ExecutorService longtimeExecutor() {
        if (itEnv.get()){
            // 是否是集成测试环境
            return CallerRunsExecutor.getInstance();
        }
        return new ThreadPoolExecutor(1, 10,
                60L,
                TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(2),
                new CustomizableThreadFactory("xxxExecutor-"));
    }

然后在基础的单元测试代码中对相应的值进行设置:


    @BeforeClass
    public static void initEnv() {
        // ...
        // 是否是集成测试环境
        XXXXConfiguration.itEnv.set(true);

    }

4. 测试代码

这里通过一个main方法来测试:


    public static void main(String[] args) {
        // 测试 execute 方法;
        CallerRunsExecutor.getInstance()
                .execute(new Runnable() {
                    @Override
                    public void run() {
                        System.out.println("execute run in " + Thread.currentThread().getName());
                    }
                });

        // 测试 submit 方法;
        Future<?> future = CallerRunsExecutor.getInstance()
                .submit(new Runnable() {
                    @Override
                    public void run() {
                        System.out.println("submit run in " + Thread.currentThread().getName());
                    }
                });

        try {
            Object result = future.get();
        } catch (Exception e) {
            e.printStackTrace();
        }
        // 正常输出
        System.out.println("main in " + Thread.currentThread().getName());

    }

5. 测试结果

测试结果为:

execute run in main
submit run in main
main in main

结果符合预期。

应用到我们的单元测试环境之中,也是符合预期的。

6. 相关问题

  • 1、注意限制使用环境, 不要影响生产;
  • 2、需要演示多个线程交互执行的某些代码可能会有问题;

日期: 2024年05月15日
作者: 铁锚 at CSDN

相关推荐

  1. 调用自己干活特殊线

    2024-05-16 10:54:10       30 阅读
  2. SpringBoot 线异步调用

    2024-05-16 10:54:10       44 阅读
  3. 任务调度与执行C++线

    2024-05-16 10:54:10       24 阅读
  4. 40.任务调度线

    2024-05-16 10:54:10       30 阅读
  5. 信号量&线&读者写模型

    2024-05-16 10:54:10       24 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-05-16 10:54:10       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-05-16 10:54:10       106 阅读
  3. 在Django里面运行非项目文件

    2024-05-16 10:54:10       87 阅读
  4. Python语言-面向对象

    2024-05-16 10:54:10       96 阅读

热门阅读

  1. Scala学习3: 字符串

    2024-05-16 10:54:10       29 阅读
  2. 教你拥有一个优雅的 Controller

    2024-05-16 10:54:10       29 阅读
  3. 【分布式】zookeeper遇到问题与解决

    2024-05-16 10:54:10       29 阅读
  4. Kotlin高阶函数用法之一

    2024-05-16 10:54:10       33 阅读
  5. 谈谈 HTTP 的方法

    2024-05-16 10:54:10       32 阅读