- 初始化一个线程池(核心线程数为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 来创建新的异步线程
- 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();
}
}
- 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那种会把异步的任务加入到我们的线程池中