Java多线程之ExecutorService.invokeAll()
1.ThreadExecutorConfig线程池的配置
package com.fn.config.threads;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.*;
@Configuration
@EnableAsync
public class ThreadExecutorConfig implements AsyncConfigurer
{
private final static int CORE_POOL_SIZE=2;
private final static int MAX_POOL_SIZE=10;
private final static int QUEUE_NUMBER=99999;
private final static String THREAD_NAME="asyncExecutor-";
private final static int KEEP_ALIVE_SECONDS=30;
@Bean("asyncExecutor")
public Executor asyncExecutor() {
ThreadPoolTaskExecutor executor = new VisiableThreadPoolTaskExecutor();
int curSystemThreads = Runtime.getRuntime().availableProcessors() * 2;
executor.setCorePoolSize(CORE_POOL_SIZE);
executor.setMaxPoolSize(curSystemThreads);
executor.setQueueCapacity(QUEUE_NUMBER);
executor.setThreadNamePrefix(THREAD_NAME);
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.setKeepAliveSeconds(KEEP_ALIVE_SECONDS);
executor.initialize();
return executor;
}
@Bean
public ExecutorService getThreadPool(){
int curSystemThreads = Runtime.getRuntime().availableProcessors() * 2;
return Executors.newFixedThreadPool(curSystemThreads);
}
}
2.VisiableThreadPoolTaskExecutor
package com.fn.config.threads;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.util.concurrent.ListenableFuture;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadPoolExecutor;
public class VisiableThreadPoolTaskExecutor extends ThreadPoolTaskExecutor {
private static final Logger logger = LoggerFactory.getLogger(VisiableThreadPoolTaskExecutor.class);
private void showThreadPoolInfo(String prefix) {
ThreadPoolExecutor threadPoolExecutor = getThreadPoolExecutor();
if (null == threadPoolExecutor) {
return;
}
logger.info("{}, {},taskCount [{}], completedTaskCount [{}], activeCount [{}], queueSize [{}]",
this.getThreadNamePrefix(),
prefix,
threadPoolExecutor.getTaskCount(),
threadPoolExecutor.getCompletedTaskCount(),
threadPoolExecutor.getActiveCount(),
threadPoolExecutor.getQueue().size());
}
@Override
public void execute(Runnable task) {
showThreadPoolInfo("1. do execute");
super.execute(task);
}
@Override
public void execute(Runnable task, long startTimeout) {
showThreadPoolInfo("2. do execute");
super.execute(task, startTimeout);
}
@Override
public Future<?> submit(Runnable task) {
showThreadPoolInfo("1. do submit");
return super.submit(task);
}
@Override
public <T> Future<T> submit(Callable<T> task) {
showThreadPoolInfo("2. do submit");
return super.submit(task);
}
@Override
public ListenableFuture<?> submitListenable(Runnable task) {
showThreadPoolInfo("1. do submitListenable");
return super.submitListenable(task);
}
@Override
public <T> ListenableFuture<T> submitListenable(Callable<T> task) {
showThreadPoolInfo("2. do submitListenable");
return super.submitListenable(task);
}
}
3.使用线程进行批量操作
public void bachSave(List<FireControlTeamAndEquipmentSaveDto> list) {
Set<Callable<String>> callables = new HashSet<>();
for (FireControlTeamAndEquipmentSaveDto dto : list) {
callables.add(new Callable<String>() {
@Override
public String call() throws Exception {
contingencyReserveFeignClient.fireControlTeamSave(dto);
logger.info("success");
return "success";
}
});
}
try {
executorService.invokeAll(callables);
} catch (Exception e) {
e.printStackTrace();
logger.info("批量写入异常");
}
}