多线程处理List数据
多线程分段处理List集合
场景:大数据List集合,需要对List集合中的数据进行较耗时操作
解决方案:
- List集合分段,
- 动态创建线程池newFixedThreadPool
- 将耗时操作在多线程中实现
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
/**
* @author tulinli
* @since 0.1.1-SNAPSHOT , 2020/6/12
*/
public class testFixedThreadPool {
public static void main(String[] args) throws Exception {
// 开始时间
long start = System.currentTimeMillis();
List<String> list = new ArrayList<String>();
for (int i = 1; i <= 3001; i++) {
list.add(i + "");
}
// 每500条数据开启一条线程
int threadSize = 500;
// 总数据条数
int dataSize = list.size();
// 线程数
int threadNum = dataSize / threadSize + 1;
if (dataSize % threadSize == 0) {
threadNum = threadNum -1;
}
// 创建一个线程池
ExecutorService exec = Executors.newFixedThreadPool(threadNum);
// 定义一个任务集合
List<Callable<String>> tasks = new ArrayList<Callable<String>>();
Callable<String> task = null;
List<String> cutList = null;
for (int i = 0; i < threadNum; i++) {
// 确定每条线程的数据
if (i == threadNum - 1) {
cutList = list.subList(threadSize * i, dataSize);
} else {
cutList = list.subList(threadSize * i, threadSize * (i + 1));
}
// System.out.println("第" + (i + 1) + "组:" + cutList.toString());
final List<String> listStr = cutList;
task = new Callable<String>() {
@Override
public String call() throws Exception {
// 线程处理逻辑
System.out.println(Thread.currentThread().getName() + "线程:" + listStr);
return Thread.currentThread().getName();
}
};
// 这里提交的任务容器列表和返回的Future列表存在顺序对应的关系
tasks.add(task);
}
List<Future<String>> results = exec.invokeAll(tasks);
for (Future<String> future : results) {
//每个线程返回的数据处理,有顺序对应关系
System.out.println(future.get());
}
// 关闭线程池
exec.shutdown();
System.out.println("线程任务执行结束");
System.err.println("执行任务消耗了 :" + (System.currentTimeMillis() - start) + "毫秒");
}
}
注意:当多线程逻辑中需要发送请求时,易出错