逻辑:
每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;
}
}
//结束
}
}