使用Spring ThreadPoolTaskExecutor实现多线程任务
我们为何使用多线程,之前已经有讲过了,为了更快的处理多个任务,分割任务,或者调用多个毫无关联的第三方服务
其实spring就提供了ThreadPoolTaskExecutor这个类来实现线程池,线程池是啥,可以理解为数据源,或者有一堆线程的池子也行
在spring配置中我们可以写好如下代码(大致意思都在注释中,不多说了,百度也一堆):
<bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor"> <!-- 核心线程数 --> <property name="corePoolSize" value="5" /> <!-- 最大线程数 --> <property name="maxPoolSize" value="10" /> <!-- 队列最大长度 >=mainExecutor.maxSize --> <property name="queueCapacity" value="25" /> <!-- 线程池维护线程所允许的空闲时间 --> <property name="keepAliveSeconds" value="3000" /> <!-- 线程池对拒绝任务(无线程可用)的处理策略 ThreadPoolExecutor.CallerRunsPolicy策略 ,调用者的线程会执行该任务,如果执行器已关闭,则丢弃. --> <property name="rejectedExecutionHandler"> <bean class="java.util.concurrent.ThreadPoolExecutor$CallerRunsPolicy" /> </property> </bean>
然后定义一个component组件,然后线程的引用就十分简单了,只要把这个线程扔进这个线程池子就行了
@Component public class FileCutter { @Autowired private TaskExecutor taskExecutor; public void filesMng(String path, String fileName) { this.taskExecutor.execute(new CutFilesThread(path,fileName)); } private class CutFilesThread implements Runnable { private String path; private String fileName; private CutFilesThread(String path, String fileName) { super(); this.path = path; this.fileName = fileName; } @Override public void run() { System.out.println("barry... run..."); // display(path, fileName); } }
最后在你所需要的地方就可以调用这个组件了,不论是service还是controller都行
@Autowired private FileCutter fileCutter; @RequestMapping("/cut") @ResponseBody public Object cut(){ fileCutter.filesMng("your path", "your fileName"); return "success"; }
如果不用线程处理,那么使用消息队列来处理大数据量操作,文件操作,或者并发,都可以。