最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

java并行流處理具體方案講解

 更新時間:2026年02月04日 10:33:41   作者:~??  
并行流是Java?8引入的一個強大工具,可以幫助我們充分利用多核處理器的性能,加速數(shù)據(jù)處理過程,這篇文章主要介紹了java并行流處理的相關資料,文中通過代碼介紹的非常詳細,需要的朋友可以參考下

當我們需要調(diào)用多次調(diào)用第三方接口,我們采用并行流處理的方式發(fā)送請求。

實際場景:第三方給了一個表,我需要對遍歷整個表,調(diào)用表中的所有地址并解析json獲取數(shù)據(jù)

常規(guī)思維:如果使用for循環(huán)遍歷,一次發(fā)送http請求,所有請求都是串行,如果一個請求需要1秒,25個請求就需要25秒。

解法方案:思路 :異步請求,多線程發(fā)送http。

具體方案:

方案一:自定義線程池,定義請求方法,使用for循環(huán)講請求添加到線程詞。

方案二(推薦):異步請求注解,使用springboot的@Async注解,完美解決,編碼量少。

方案三:并行流(Parallel Stream)。

以下是方案三詳解:

并行流(Parallel Stream)深度解析

一、并行流是什么?

并行流是Java 8引入的一個特性,它允許你將流操作并行執(zhí)行,利用多核處理器的優(yōu)勢來加速處理。

java

// 順序流 vs 并行流
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

// 1. 順序流(默認)
int sumSequential = numbers.stream()
    .reduce(0, Integer::sum);

// 2. 并行流
int sumParallel = numbers.parallelStream()
    .reduce(0, Integer::sum);

// 3. 將順序流轉為并行流
int sumParallel2 = numbers.stream()
    .parallel()
    .reduce(0, Integer::sum);

二、并行流的核心原理

1. 底層框架:Fork/Join框架

java

// 并行流背后是這個框架
ForkJoinPool commonPool = ForkJoinPool.commonPool();
System.out.println("并行度: " + commonPool.getParallelism()); // 通常是CPU核心數(shù)-1

2. 工作竊取算法(Work-Stealing)

text

線程A:│任務1│任務2│任務3│任務4│
線程B:│任務5│任務6│          │ ← 空閑
              ↓
線程B從線程A的隊尾"偷取"任務3來執(zhí)行

3. 數(shù)據(jù)拆分策略

java

// 并行流自動將數(shù)據(jù)拆分為多個子任務
Spliterator<T> spliterator = list.spliterator();

// 查看分割特性
int characteristics = spliterator.characteristics();
// SIZED: 知道確切大小
// SUBSIZED: 分割后的大小也確切
// ORDERED: 有順序要求

三、基本使用模式

1. 創(chuàng)建并行流

java

// 方式1:從集合創(chuàng)建
List<String> list = Arrays.asList("a", "b", "c");
Stream<String> parallelStream = list.parallelStream();

// 方式2:將順序流轉為并行流
Stream<String> parallelStream2 = list.stream().parallel();

// 方式3:從數(shù)組創(chuàng)建
String[] array = {"a", "b", "c"};
Stream<String> parallelStream3 = Arrays.stream(array).parallel();

2. 常用操作示例

映射操作(map)

java

List<String> words = Arrays.asList("hello", "world", "java", "stream");

// 順序處理
List<String> upperCaseSequential = words.stream()
    .map(String::toUpperCase)
    .collect(Collectors.toList());

// 并行處理
List<String> upperCaseParallel = words.parallelStream()
    .map(String::toUpperCase)
    .collect(Collectors.toList());

過濾操作(filter)

java

List<Integer> numbers = IntStream.range(1, 1000000).boxed().collect(Collectors.toList());

// 并行過濾偶數(shù)
List<Integer> evenNumbers = numbers.parallelStream()
    .filter(n -> n % 2 == 0)
    .collect(Collectors.toList());

歸約操作(reduce)

java

// 計算1到1000000的和(并行版本更快)
long sum = LongStream.rangeClosed(1, 1000000)
    .parallel()
    .reduce(0, Long::sum);

四、你的代碼中并行流的應用

java

private List<Map<String, String>> getInterlockResultWen13or24Level1PointValueParallel(
    Map<String, String> map, 
    List<IntermediateTable> list
) {
    // 1. 建立查找表(提升效率)
    Map<String, String> codeToTagNumber = list.stream()
        .collect(Collectors.toMap(
            IntermediateTable::getInterlockWen13or24Level1Point,
            IntermediateTable::getTagNumber,
            (v1, v2) -> v1  // 如果有重復key,取第一個
        ));
    
    // 2. 使用并行流處理
    return map.entrySet()
        .parallelStream()  // ← 關鍵!開啟并行
        .map(entry -> {
            String code = entry.getKey();
            String name = entry.getValue();
            String tagNumber = codeToTagNumber.get(code);
            
            // 3. 執(zhí)行IO操作(HTTP請求)
            String value = tagNumber != null ? getSupOSValue(tagNumber) : "0";
            
            // 4. 構建結果
            Map<String, String> resMap = new LinkedHashMap<>();
            resMap.put("name", name);
            resMap.put("value", value);
            return resMap;
        })
        .collect(Collectors.toList());  // 收集結果
}

五、性能對比:串行 vs 并行

java

public class ParallelStreamBenchmark {
    
    public static void main(String[] args) {
        // 模擬24次HTTP請求(用睡眠模擬)
        List<Integer> requestIds = IntStream.range(1, 25).boxed().collect(Collectors.toList());
        
        // 串行執(zhí)行
        long start = System.currentTimeMillis();
        List<String> sequentialResults = requestIds.stream()
            .map(id -> mockHttpRequest(id))
            .collect(Collectors.toList());
        long sequentialTime = System.currentTimeMillis() - start;
        
        // 并行執(zhí)行
        start = System.currentTimeMillis();
        List<String> parallelResults = requestIds.parallelStream()
            .map(id -> mockHttpRequest(id))
            .collect(Collectors.toList());
        long parallelTime = System.currentTimeMillis() - start;
        
        System.out.println("串行耗時: " + sequentialTime + "ms");
        System.out.println("并行耗時: " + parallelTime + "ms");
        System.out.println("加速比: " + (double)sequentialTime/parallelTime);
    }
    
    private static String mockHttpRequest(Integer id) {
        try {
            // 模擬HTTP請求延遲(100-500ms隨機)
            Thread.sleep(100 + (long)(Math.random() * 400));
            return "Response_" + id;
        } catch (InterruptedException e) {
            return "Error";
        }
    }
}

六、注意事項和最佳實踐

1. 什么時候使用并行流?

java

// ? 適合的場景
- 數(shù)據(jù)量大(>1000個元素)
- 每個元素的處理是獨立的
- 處理操作是CPU密集型或IO密集型
- 沒有順序要求(或者可以使用unordered()放棄順序)

// ? 不適合的場景
- 數(shù)據(jù)量?。?lt;100個元素)
- 處理操作簡單(如簡單的數(shù)學運算)
- 需要嚴格保持順序
- 操作有共享狀態(tài)(線程不安全)

2. 線程安全問題

java

// ? 錯誤示例:共享可變狀態(tài)
List&lt;Integer&gt; sharedList = new ArrayList&lt;&gt;();
numbers.parallelStream()
    .forEach(sharedList::add);  // 并發(fā)修改異常!

// ? 正確做法:使用線程安全收集器
List&lt;Integer&gt; safeList = numbers.parallelStream()
    .collect(Collectors.toList());
    
// ? 或者使用同步集合
List&lt;Integer&gt; synchronizedList = Collections.synchronizedList(new ArrayList&lt;&gt;());
numbers.parallelStream()
    .forEach(synchronizedList::add);

3. 性能優(yōu)化技巧

java

// 1. 使用基礎類型流避免裝箱拆箱
IntStream.range(1, 1000000)
    .parallel()
    .sum();

// 2. 使用unordered()放棄順序約束(可能提升性能)
list.parallelStream()
    .unordered()
    .filter(...)
    .collect(Collectors.toList());

// 3. 合并操作(combiner)必須是可結合的
// reduce操作需要:a ⊕ b ⊕ c = a ⊕ (b ⊕ c)

4. 控制并行度

java

// 方法1:修改系統(tǒng)屬性
System.setProperty("java.util.concurrent.ForkJoinPool.common.parallelism", "8");

// 方法2:使用自定義ForkJoinPool
ForkJoinPool customPool = new ForkJoinPool(4);
List<String> results = customPool.submit(() -> 
    list.parallelStream()
        .map(item -> process(item))
        .collect(Collectors.toList())
).get();

七、在你的具體場景中的應用建議

java

private List<Map<String, String>> getInterlockResultWen13or24Level1PointValueOptimized(
    Map<String, String> map, 
    List<IntermediateTable> list
) {
    // 1. 建立索引
    Map<String, String> codeToTag = list.stream()
        .collect(Collectors.toMap(
            IntermediateTable::getInterlockWen13or24Level1Point,
            IntermediateTable::getTagNumber,
            (v1, v2) -> v1
        ));
    
    // 2. 預計算需要請求的tagNumbers
    List<String> tagNumbers = map.keySet().stream()
        .map(codeToTag::get)
        .filter(Objects::nonNull)
        .distinct()
        .collect(Collectors.toList());
    
    // 3. 并行獲取所有值
    Map<String, String> valueCache = tagNumbers.parallelStream()
        .collect(Collectors.toMap(
            tag -> tag,
            this::getSupOSValue  // 這是你的HTTP請求方法
        ));
    
    // 4. 構建結果
    return map.entrySet().stream()
        .map(entry -> {
            String code = entry.getKey();
            String tag = codeToTag.get(code);
            String value = tag != null ? valueCache.getOrDefault(tag, "0") : "0";
            
            Map<String, String> result = new LinkedHashMap<>();
            result.put("name", entry.getValue());
            result.put("value", value);
            return result;
        })
        .collect(Collectors.toList());
}

八、調(diào)試和監(jiān)控

java

// 1. 查看并行流使用的線程
List<String> results = list.parallelStream()
    .peek(item -> System.out.println(Thread.currentThread().getName()))
    .map(...)
    .collect(Collectors.toList());

// 2. 監(jiān)控執(zhí)行時間
long start = System.nanoTime();
List<String> results = list.parallelStream()
    .map(...)
    .collect(Collectors.toList());
long duration = System.nanoTime() - start;

// 3. 使用JMH進行基準測試(推薦)
// 添加依賴:org.openjdk.jmh

九、常見陷阱

java

// 陷阱1:副作用操作
List<String> list = Arrays.asList("a", "b", "c");
StringBuilder builder = new StringBuilder();
list.parallelStream().forEach(builder::append); // ? 線程不安全

// 陷阱2:有狀態(tài)lambda
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> results = new ArrayList<>();
numbers.parallelStream()
    .filter(n -> {
        results.add(n); // ? 在lambda中修改外部狀態(tài)
        return n % 2 == 0;
    })
    .collect(Collectors.toList());

// 陷阱3:順序依賴
Optional<Integer> first = numbers.parallelStream()
    .filter(n -> n > 3)
    .findFirst(); // ?? 并行下findFirst可能變慢

PyTorch 2.9

總結

到此這篇關于java并行流處理的文章就介紹到這了,更多相關java并行流處理內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

最新評論

鸡西市| 托克托县| 甘洛县| 上杭县| 若尔盖县| 武冈市| 长春市| 沁源县| 成安县| 芒康县| 镇巴县| 陆川县| 荆州市| 龙南县| 建水县| 万全县| 玉环县| 余姚市| 舒城县| 克山县| 华安县| 吉木萨尔县| 肇东市| 宁城县| 交城县| 淳安县| 夏邑县| 镇康县| 科尔| 车致| 大港区| 红原县| 蓬溪县| 大英县| 承德县| 星座| 陵水| 阿鲁科尔沁旗| 崇明县| 台北县| 麦盖提县|