ThreadPoolTaskExecutor 使用中创建子线程的一些问题

  • 初始化一个线程池(核心线程数为1保证任务顺序执行)
	@Bean
    public ThreadPoolTaskExecutor threadPoolTaskExecutor(){
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(1);
        executor.setMaxPoolSize(1);
        return executor;
    }
  • 采用 New Thread 方式创建子线程去执行其他操作
        @Autowired
    private ThreadPoolTaskExecutor executor;

    @Test
    public void qwe() throws InterruptedException {
        for (int i = 0; i < 8; i++) {
            //任务编号
            final int task = i;
            //任务执行
            executor.execute(new Runnable() {
                @Override
                public void run() {
                    //模拟任务执行
                    log.info("任务{}开始", task);
                    sleep(500L);
                    //创建子线程执行其他操作
                    Thread thread = new Thread(new Runnable() {
                        @Override
                        public void run() {
                            //模拟任务执行
                            sleep(task * 500L);
                            log.info("任务{}执行中", task);
                        }
                    });
                    thread.start();
                    sleep(500L);
                    log.info("任务{}结束", task);
                }
            });
        }
        sleep(50000L);
    }

    private static void sleep(Long m) {
        try {
            Thread.sleep(m);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
  • 执行结果日志
[ INFO ] [2020-03-20 14:58:24.024] ScheduledTest [115] [threadPoolTaskExecutor-1] - 任务0开始
[ INFO ] [2020-03-20 14:58:24.526] ScheduledTest [121] [Thread-5] - 任务0执行中
[ INFO ] [2020-03-20 14:58:25.027] ScheduledTest [126] [threadPoolTaskExecutor-1] - 任务0结束
[ INFO ] [2020-03-20 14:58:25.027] ScheduledTest [115] [threadPoolTaskExecutor-1] - 任务1开始
[ INFO ] [2020-03-20 14:58:26.028] ScheduledTest [126] [threadPoolTaskExecutor-1] - 任务1结束
[ INFO ] [2020-03-20 14:58:26.028] ScheduledTest [115] [threadPoolTaskExecutor-1] - 任务2开始
[ INFO ] [2020-03-20 14:58:26.028] ScheduledTest [121] [Thread-6] - 任务1执行中
[ INFO ] [2020-03-20 14:58:27.030] ScheduledTest [126] [threadPoolTaskExecutor-1] - 任务2结束
[ INFO ] [2020-03-20 14:58:27.030] ScheduledTest [115] [threadPoolTaskExecutor-1] - 任务3开始
[ INFO ] [2020-03-20 14:58:27.529] ScheduledTest [121] [Thread-7] - 任务2执行中
[ INFO ] [2020-03-20 14:58:28.032] ScheduledTest [126] [threadPoolTaskExecutor-1] - 任务3结束
[ INFO ] [2020-03-20 14:58:28.032] ScheduledTest [115] [threadPoolTaskExecutor-1] - 任务4开始
[ INFO ] [2020-03-20 14:58:29.032] ScheduledTest [121] [Thread-8] - 任务3执行中
[ INFO ] [2020-03-20 14:58:29.033] ScheduledTest [126] [threadPoolTaskExecutor-1] - 任务4结束
[ INFO ] [2020-03-20 14:58:29.033] ScheduledTest [115] [threadPoolTaskExecutor-1] - 任务5开始
[ INFO ] [2020-03-20 14:58:30.033] ScheduledTest [126] [threadPoolTaskExecutor-1] - 任务5结束
[ INFO ] [2020-03-20 14:58:30.033] ScheduledTest [115] [threadPoolTaskExecutor-1] - 任务6开始
[ INFO ] [2020-03-20 14:58:30.532] ScheduledTest [121] [Thread-9] - 任务4执行中
[ INFO ] [2020-03-20 14:58:31.035] ScheduledTest [126] [threadPoolTaskExecutor-1] - 任务6结束
[ INFO ] [2020-03-20 14:58:31.035] ScheduledTest [115] [threadPoolTaskExecutor-1] - 任务7开始
[ INFO ] [2020-03-20 14:58:32.033] ScheduledTest [121] [Thread-10] - 任务5执行中
[ INFO ] [2020-03-20 14:58:32.036] ScheduledTest [126] [threadPoolTaskExecutor-1] - 任务7结束
[ INFO ] [2020-03-20 14:58:33.535] ScheduledTest [121] [Thread-11] - 任务6执行中
[ INFO ] [2020-03-20 14:58:35.036] ScheduledTest [121] [Thread-12] - 任务7执行中

结论1:当再线程池中的任务中创建新线程时,该子线程的与该线程池中的父线程无关,异步执行

  • 使用@Async 来创建新的异步线程
  1. Test类
@Autowired
    private ThreadPoolTaskExecutor executor;
    @Autowired
    private TestService testService;

    @Test
    public void qwe() throws InterruptedException {
        for (int i = 0; i < 8; i++) {
            //任务编号
            final int task = i;
            //任务执行
            executor.execute(new Runnable() {
                @Override
                public void run() {
                    //模拟任务执行
                    log.info("任务{}开始", task);
                    sleep(500L);
                    //创建子线程执行其他操作
                    try {
                        testService.test(task);
                    } catch (InterruptedException e) {
                        log.info(e.getMessage());
                    }
                    sleep(500L);
                    log.info("任务{}结束", task);
                }
            });
        }
        sleep(50000L);
    }

    private static void sleep(Long m) {
        try {
            Thread.sleep(m);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
  1. TestService
@Slf4j
@Service
public class TestServiceImpl implements TestService {

    @Async
    @Override
    public void test(int task) throws InterruptedException {
        Thread.sleep(task * 500L);
        log.info("任务{}执行中", task);
    }
}
  • 执行结果日志
[ INFO ] [2020-03-20 15:09:36.463] ScheduledTest [122] [threadPoolTaskExecutor-1] - 任务0开始
[ INFO ] [2020-03-20 15:09:37.468] ScheduledTest [131] [threadPoolTaskExecutor-1] - 任务0结束
[ INFO ] [2020-03-20 15:09:37.468] ScheduledTest [122] [threadPoolTaskExecutor-1] - 任务1开始
[ INFO ] [2020-03-20 15:09:38.469] ScheduledTest [131] [threadPoolTaskExecutor-1] - 任务1结束
[ INFO ] [2020-03-20 15:09:38.470] ScheduledTest [122] [threadPoolTaskExecutor-1] - 任务2开始
[ INFO ] [2020-03-20 15:09:39.471] ScheduledTest [131] [threadPoolTaskExecutor-1] - 任务2结束
[ INFO ] [2020-03-20 15:09:39.471] ScheduledTest [122] [threadPoolTaskExecutor-1] - 任务3开始
[ INFO ] [2020-03-20 15:09:40.472] ScheduledTest [131] [threadPoolTaskExecutor-1] - 任务3结束
[ INFO ] [2020-03-20 15:09:40.472] ScheduledTest [122] [threadPoolTaskExecutor-1] - 任务4开始
[ INFO ] [2020-03-20 15:09:41.473] ScheduledTest [131] [threadPoolTaskExecutor-1] - 任务4结束
[ INFO ] [2020-03-20 15:09:41.473] ScheduledTest [122] [threadPoolTaskExecutor-1] - 任务5开始
[ INFO ] [2020-03-20 15:09:42.475] ScheduledTest [131] [threadPoolTaskExecutor-1] - 任务5结束
[ INFO ] [2020-03-20 15:09:42.475] ScheduledTest [122] [threadPoolTaskExecutor-1] - 任务6开始
[ INFO ] [2020-03-20 15:09:43.476] ScheduledTest [131] [threadPoolTaskExecutor-1] - 任务6结束
[ INFO ] [2020-03-20 15:09:43.476] ScheduledTest [122] [threadPoolTaskExecutor-1] - 任务7开始
[ INFO ] [2020-03-20 15:09:44.478] ScheduledTest [131] [threadPoolTaskExecutor-1] - 任务7结束
[ INFO ] [2020-03-20 15:09:44.478] com.sunrate.gateway.service.impl.TestServiceImpl [20] [threadPoolTaskExecutor-1] - 任务0执行中
[ INFO ] [2020-03-20 15:09:44.979] com.sunrate.gateway.service.impl.TestServiceImpl [20] [threadPoolTaskExecutor-1] - 任务1执行中
[ INFO ] [2020-03-20 15:09:45.979] com.sunrate.gateway.service.impl.TestServiceImpl [20] [threadPoolTaskExecutor-1] - 任务2执行中
[ INFO ] [2020-03-20 15:09:47.479] com.sunrate.gateway.service.impl.TestServiceImpl [20] [threadPoolTaskExecutor-1] - 任务3执行中
[ INFO ] [2020-03-20 15:09:49.480] com.sunrate.gateway.service.impl.TestServiceImpl [20] [threadPoolTaskExecutor-1] - 任务4执行中
[ INFO ] [2020-03-20 15:09:51.980] com.sunrate.gateway.service.impl.TestServiceImpl [20] [threadPoolTaskExecutor-1] - 任务5执行中
[ INFO ] [2020-03-20 15:09:54.981] com.sunrate.gateway.service.impl.TestServiceImpl [20] [threadPoolTaskExecutor-1] - 任务6执行中
[ INFO ] [2020-03-20 15:09:58.482] com.sunrate.gateway.service.impl.TestServiceImpl [20] [threadPoolTaskExecutor-1] - 任务7执行中
  • 结论2:再线程池的任务中使用异步注解创建出的任务会进入该线程池的队列中排队,而不会像上面那样创建一个新的线程去执行

2020.03.25
产生的原因,首先要了解@Async注解,该注解的原理就是把该任务加入到一个异步的线程池中执行,只不过我们不用实现而spring有默认实现我们平时没有发现而已,而刚好我们这个案例中我们自己创建了一个线程池 ThreadPoolTaskExecutor,我们不妨看看这个类

public class ThreadPoolTaskExecutor extends ExecutorConfigurationSupport implements AsyncListenableTaskExecutor, SchedulingTaskExecutor

正因@Async的原理是将任务放到线程池中,所以当我们创建了一个线程池后,自然而然的就替代了spring的默认线程池而成为了异步注解的线程池。所以才会出现例2那种会把异步的任务加入到我们的线程池中

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值