Stream并行流

Stream并行流

1.什么是Stream并行流

​ Stream并行流是Java 8引入的一种并行计算模型,它允许对集合类型数据进行高效的并行处理。底层实现使用了多线程技术,利用多个处理线程同时对数据进行处理,以加快计算速度。

​ 在使用并行流时,数据流会被分成多个独立的子流,并行执行处理操作。每个子流都会被分配到不同的线程上,同时进行处理。最终,处理结果会被合并为一个整体结果。并行流的实现基于Fork/Join框架,它是Java中用于处理递归型分治任务的标准框架。Fork/Join框架使用了一种递归的分治策略,将任务划分为多个小任务,然后并行执行这些小任务,并最终将结果合并起来。在并行流的实现中,数据会被分割成多个数据块,每个数据块会被分配给一个线程进行处理。每个线程只负责处理自己分配到的数据块,避免了线程之间的竞争和同步操作。

2.用法

​ 使用并行流时,可以通过使用.parallel()方法将顺序流转换为并行流。例如,对一个List进行操作,可以使用list.stream().parallel()来创建并行流或者list.parallelStream()来创建并行流。

​ ist.stream().parallel()list.parallelStream()`都是用于将一个List转换成并行流的方法,它们的作用是相同的。

​ 然而,它们的主要区别在于语法和可读性。stream().parallel()是在List实例上调用stream()方法后再调用parallel()方法,而parallelStream()是直接在List实例上调用parallelStream()方法。这个区别主要是出于语言设计的考虑,让代码更易读和易懂。parallelStream()的写法更简洁,直接表达了意图——将List转换成并行流。而stream().parallel()稍微冗长一些,需要额外的方法调用。实际上,这两种写法在功能和性能上是相同的,它们都可以将List转换为并行流,并且在并行处理数据时,使用相同的底层实现机制。

以下是两种写法的示例代码:

import java.util.ArrayList;
import java.util.List;

public class ParallelStreamExample {
    public static void main(String[] args) {
        List<Integer> numbers = new ArrayList<>();
        numbers.add(1);
        numbers.add(2);
        numbers.add(3);
        numbers.add(4);
        numbers.add(5);

        // 使用stream().parallel()
        numbers.stream().parallel()
                .forEach(number -> {
                    System.out.println("Processing number: " + number);
                });

        // 使用parallelStream()
        numbers.parallelStream()
                .forEach(number -> {
                    System.out.println("Processing number: " + number);
                });
    }
}
3.场景

外部List文件数据,要在通过文件上传接口上传到本地服务器,并获取文件地址.原写法,forEach遍历后调用上传接口,速度很慢,修改为并行流后多线程下载,速度有所提高.

public APIResult<List<Attach>> transferFiles(@RequestBody List<Attach> attaches) throws IOException {
    APIResult<List<Attach>> result = new APIResult<>();
    ArrayList<Attach> newAttaches = new ArrayList<>();
    HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
    RequestConfig requestConfig = RequestConfig.custom().build();
    CloseableHttpClient httpClient = httpClientBuilder.setDefaultRequestConfig(requestConfig).build();
    //遍历传入文件List
    for (ContractAttach attache : attaches) {
        //...处理数据
        MultipartFile newFile = attache.get();
        //...调用上传文件
        APIResult<AttachmentPo> attachmentResult = iUploadService.upload(newFile);
        newAttaches.add(attachmentResult.getData);
                        
    }
        
    return result;
}

    //并行
    attaches.parallelStream()
            .forEach(attache -> {
                //...处理数据
                MultipartFile newFile = attache.get();
                //...调用上传文件
                APIResult<AttachmentPo> attachmentResult = iUploadService.upload(newFile);
                newAttaches.add(attachmentResult.getData);
            };
        
4.注意

​ 在使用stream.foreach时这个遍历没有线程安全问题,但是使用parallelStream就会有线程安全问题,所有在parallelStream里面使用的外部变量,比如集合一定要使用线程安全集合,不然就会引发多线程安全问题。

​ 需要注意的是,并行流的效果取决于具体的应用场景和硬件资源。在某些情况下,并行流可以显著提高程序的性能,但在其他情况下,它可能会导致性能下降。因此,在使用并行流时,建议进行性能测试和调优,以确定是否使用并行流以及如何使用它。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值