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

发布于:2024-05-19 ⋅ 阅读:(163) ⋅ 点赞:(0)

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

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


网站公告

今日签到

点亮在社区的每一天
去签到