版权声明:本文为博主原创文章,转载请注明出处。 https://blog.csdn.net/libra_ts/article/details/80287613
前言
当需要进行一项耗时操作时,就需要用到子线程,用到子线程时可以选择new一个子线程来操作,这样不是不行,但是效率会很低。而且消耗内存,所以就需要引用线程池来解决问题
- 配置ThreadPoolTaskExecutor
<bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
<!-- 线程池维护线程的最少数量 -->
<property name="corePoolSize" value="5"/>
<!-- 允许的空闲时间 -->
<property name="keepAliveSeconds" value="200"/>
<!-- 线程池维护线程的最大数量 -->
<property name="maxPoolSize" value="10"/>
<!-- 缓存队列 -->
<property name="queueCapacity" value="20"/>
</bean>
- 线程池请求工具类
public class TaskThreadSender {
private static Logger log = LoggerFactory.getLogger(TaskThreadSender.class);
private ThreadPoolTaskExecutor executor;
public TaskThreadSender(ThreadPoolTaskExecutor executor) {
this.executor = executor;
}
public void send(String fileName){
executor.execute(new Runnable() {
@Override
public void run() {
long beginTime = System.currentTimeMillis();
log.info("{}开始复制...",Thread.currentThread().getName());
//做耗时操作
long endTime = System.currentTimeMillis();
log.info("{}复制完成,耗时{}ms",Thread.currentThread().getName(),endTime-beginTime);
}
});
}
}
- 调用
public class UserServiceImpl implements UserServive{
@Autowired
private ThreadPoolTaskExecutor executor;
@Override
public boolean testTaskThread() {
for (int i = 0; i < 10; i++) {
TaskThreadSender taskThreadSender = new TaskThreadSender(executor);
taskThreadSender.send("name"+i);
}
return false;
}
}
- 结果
TaskThreadSender.run<24> taskExecutor-2开始复制...
TaskThreadSender.run<24> taskExecutor-1开始复制...
TaskThreadSender.run<24> taskExecutor-3开始复制...
TaskThreadSender.run<24> taskExecutor-4开始复制...
TaskThreadSender.run<24> taskExecutor-5开始复制...
TaskThreadSender.run<45> taskExecutor-4复制完成,耗时455ms
TaskThreadSender.run<24> taskExecutor-4开始复制...
TaskThreadSender.run<45> taskExecutor-5复制完成,耗时515ms
TaskThreadSender.run<24> taskExecutor-5开始复制...
TaskThreadSender.run<45> taskExecutor-3复制完成,耗时541ms
TaskThreadSender.run<24> taskExecutor-3开始复制...
TaskThreadSender.run<45> taskExecutor-2复制完成,耗时592ms
TaskThreadSender.run<24> taskExecutor-2开始复制...
TaskThreadSender.run<45> taskExecutor-1复制完成,耗时612ms
TaskThreadSender.run<24> taskExecutor-1开始复制...
TaskThreadSender.run<45> taskExecutor-4复制完成,耗时450ms
TaskThreadSender.run<45> taskExecutor-5复制完成,耗时498ms
TaskThreadSender.run<45> taskExecutor-3复制完成,耗时479ms
TaskThreadSender.run<45> taskExecutor-1复制完成,耗时416ms
TaskThreadSender.run<45> taskExecutor-2复制完成,耗时449ms
- 总结
可以很清楚的看到,进行了十次耗时操作,但是只用到了5个子线程,每次用完都会还回去,这样避免内存浪费,也避免了子线程无法回收的情况。