使用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";
    }

 

如果不用线程处理,那么使用消息队列来处理大数据量操作,文件操作,或者并发,都可以。

posted @ 2017-02-04 17:01  风间影月  阅读(15020)  评论(0编辑  收藏  举报