目錄
項目場景
問題描述
解決方案:
方法一:沒有返回值,直接在任務里完成計算
方法二:有返回值
最后
項目場景
前臺通過模板批量上傳數(shù)據(jù)到后臺
問題描述
后臺使用常規(guī)方法處理數(shù)據(jù),效率低下
解決方案:
使用多線程線程池實現(xiàn)
方法一:沒有返回值,直接在任務里完成計算
package com.lwk.test;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class ThreadPoolExample {
public static void main(String[] args) throws InterruptedException {
// 創(chuàng)建一個包含 10 個線程的線程池
ExecutorService executorService = Executors.newFixedThreadPool(10);
// 創(chuàng)建一個包含 10000 個元素的 List
List<Integer> list = new ArrayList<>();
for (int i = 0; i < 10001; i++) {
list.add(i);
}
// 將 List 分成 10 個子 List,每個子 List 包含 1000 個元素
List<List<Integer>> subLists = new ArrayList<>();
int subListSize = 1000;
for (int i = 0; i < list.size(); i += subListSize) {
subLists.add(list.subList(i, Math.min(i + subListSize, list.size())));
}
// 提交每個子 List 的處理任務給線程池
for (List<Integer> subList : subLists) {
executorService.submit(new Task(subList));
}
// 等待線程池中所有任務執(zhí)行完畢
executorService.shutdown();
executorService.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
// 打印處理結果
System.out.println("List size: " + list.size());
System.out.println("Sum of elements: " + Task.getSum());
}
static class Task implements Runnable {
private List<Integer> list;
private static long sum = 0;
public Task(List<Integer> list) {
this.list = list;
}
@Override
public void run() {
long subSum = 0;
for (int i : list) {
subSum += i;
}
synchronized (Task.class) {
sum += subSum;
}
}
public static long getSum() {
return sum;
}
}
}
方法二:有返回值
除了創(chuàng)建線程池和分割 List 的過程外,主要的變化是將 Task 類改為實現(xiàn) Callable 接口,并返回子 List 的和。使用 CompletionService 提交任務和獲取任務執(zhí)行結果,從而減少了線程池的等待時間,提高了執(zhí)行效率。最后,將每個子 List 的和累加起來,打印處理結果。
package com.lwk.test;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
public class ThreadPoolExample2 {
public static void main(String[] args) throws InterruptedException, ExecutionException {
// 創(chuàng)建一個包含 10 個線程的線程池
ExecutorService executorService = Executors.newFixedThreadPool(10);
// 創(chuàng)建一個 CompletionService,用于提交任務和獲取任務執(zhí)行結果
CompletionService<Long> completionService = new ExecutorCompletionService<>(executorService);
// 創(chuàng)建一個包含 10000 個元素的 List
List<Integer> list = new ArrayList<>();
for (int i = 0; i < 10001; i++) {
list.add(i);
}
// 將 List 分成 10 個子 List,每個子 List 包含 1000 個元素
List<List<Integer>> subLists = new ArrayList<>();
int subListSize = 1000;
for (int i = 0; i < list.size(); i += subListSize) {
subLists.add(list.subList(i, Math.min(i + subListSize, list.size())));
}
// 提交每個子 List 的處理任務給 CompletionService
for (List<Integer> subList : subLists) {
completionService.submit(new Task(subList));
}
// 獲取每個任務的執(zhí)行結果,并將結果累加起來
long sum = 0;
for (int i = 0; i < subLists.size(); i++) {
Future<Long> future = completionService.take();
sum += future.get();
}
// 打印處理結果
System.out.println("List size: " + list.size());
System.out.println("Sum of elements: " + sum);
// 關閉線程池
executorService.shutdown();
}
static class Task implements Callable<Long> {
private List<Integer> list;
public Task(List<Integer> list) {
this.list = list;
}
@Override
public Long call() throws Exception {
long subSum = 0;
for (int i : list) {
subSum += i;
}
return subSum;
}
}
}
最后
如果改為項目中使用的話,需要將 【創(chuàng)建一個包含 10000 個元素的 List】改為自己的數(shù)據(jù)集即可!
需要注意的是:在使用線程池時,需要選擇合適的線程池大小,以避免創(chuàng)建過多的線程導致系統(tǒng)資源耗盡!
還有一點:也不要盲目的去開多個線程。如果你的服務器是單cpu單核開多線程反而會增加上下文損耗,從而降低程序執(zhí)行效率。能開多少個線程,理論是這樣計算的:邏輯cpu個數(shù) =?(物理cpu個數(shù) * 每個cpu的核心數(shù) * 超線程數(shù)),命令見如下:
1.查看物理cpu個數(shù),也就是實物cpu的個數(shù)
cat /proc/cpuinfo| grep "physical id"| sort| uniq| wc -l
2.查看每個cpu的core,也就是常說的核心數(shù)
cat /proc/cpuinfo| grep "cpu cores"| uniq文章來源:http://www.zghlxwxcb.cn/news/detail-482943.html
今天的分享就到這里了,如果問題歡迎留言指正!?文章來源地址http://www.zghlxwxcb.cn/news/detail-482943.html
到了這里,關于java多線程處理list,速度提升嗖嗖的!的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!