[springboot] 异步+定时任务的坑

逻辑:

每6s扫描一遍文件夹A,将文件夹A里的所有文件异步复制到文件夹B

坑点:由于文件数目很多,多线程12345678,线程1结束后就会刷新定时任务进入下一周期,而此时线程678还在里面复制,就会出现重复复制找不到文件报错的问题

需要用Future 等所有线程搞完再一起return;

 

思路:

异步:Async  定时任务:Scheduled   文件操作:hutool

 

实现:

1.配置线程池,新建TaskPoolConfig配置类

package com.gzgdata.xinshagatepromotion.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;

@EnableAsync
@Configuration
class TaskPoolConfig {

    @Bean("taskExecutor1")
    public Executor taskExecutor1() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(200);
        executor.setMaxPoolSize(200);
        executor.setQueueCapacity(1000);
        executor.setKeepAliveSeconds(60);
        executor.setThreadNamePrefix("taskExecutor1-");
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        return executor;
    }
}

 

2. 新建AsyncFun配置类 用来写需要异步的逻辑

import cn.hutool.core.io.FileUtil;

@Component
public class AsyncFun {

    @Async("taskExecutor1")  //需要配置对应的线程池
    public Future doTask(文件名,路径,目标路径){ //你想要多线程跑的逻辑1     
        //.....
        //文件夹复制
        FileUtil.copy(FileUtil.file(路径 + "/" + 文件名), FileUtil.file(目标路径), true覆盖写入);
        
        return new AsyncResult(null);
    }


    @Async("taskExecutor2")
    public Future doTask2(){ //你想要多线程跑的逻辑2  
        //.....

        return new AsyncResult(null);
    }
}

 

3.定时任务里调用,新建TimeTask配置类

import java.util.concurrent.Future;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import cn.hutool.core.io.FileUtil;

@Component
@Configuration      //1.主要用于标记配置类,兼备Component的效果。
@EnableScheduling   // 2.开启定时任务
public class TimeTask {
    @Autowired
    AsyncFun asyncFun;
    
    @Scheduled(fixedDelay = 6000) 
    //周期6s fixedDelay如果有超过6s的任务下一周期会延时等待
    private void fuck(){
        
            
        //扫描文件夹A,维护文件夹A的文件名列表Lists
        List<String> Lists = new ArrayList<>();
        try {
            Lists = FileUtil.listFileNames(路径);
        } catch (Exception e) {
            logger6.info("扫描文件夹失败:原因:" + e);
        }        

        //Future
        List<Future> futureList = new ArrayList<>();

        //遍历Lists 进行复制
        for(String filename:Lists){
            try{
               Future future=asyncFun.doTask(文件名,路径,目标路径);
               futureList.add(future);
            }
            catch(Exception e){
               logger6.info("多线程出错"+e);
            }
        }   
        
        //让所有线程结束后一起返回
        while (true) {
            if (null != futureList) {
                boolean isAllDone = true;
                for (Future future : futureList) {
                    if (null == future || !future.isDone()) {
                        isAllDone = false;
                    }
                }
                if (isAllDone) break;
            }
        }
        //结束
    }
    
}

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值