多線程分段處理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) + "毫秒");
}
}
注意:當多線程邏輯中需要發送請求時,易出錯