Java8 遍历List 使用stream().parallel()并发安全

1. parallelStream是什么:

复制代码
 java 8引入了并行流的概念来进行并行处理,而并行流(Parallel Stream)利用所有可用CPU内核的优势,并行处理任务。其原理(Parallel Stream)是可以把大任务分成多个小任务执行, 最后再把执行结果进行合并, ForkJoinPool用工作窃取算法实现。

2.Java8的paralleStream是线程安全吗

复制代码
    一个简单例子,循环1000000次,往list中插入数据,最后看list的长度。
javascript 复制代码
public class TestParallel {
    public static void main(String[] args) {
        StopWatch stopWatch = new StopWatch();
        List<Integer> list = new ArrayList<>();
        stopWatch.start("TaskOneName");
        IntStream.range(0, 1000000).forEach(list::add);
        stopWatch.stop();
        System.out.println("list size:" + list.size());
        System.out.println("当前任务名称:" + stopWatch.currentTaskName() +" 执行时间:" + stopWatch.getTotalTimeMillis());
 
    }
}

执行时间以及list 中的size见下图

使用并发流

javascript 复制代码
public class TestParallel {
   public static void main(String[] args) {
       StopWatch stopWatch = new StopWatch();
       List<Integer> list = new ArrayList<>();
       stopWatch.start("TaskOneName");
       IntStream.range(0, 10000).parallel().forEach(list::add);
       stopWatch.stop();
       System.out.println("list size:" + list.size());
       System.out.println("当前任务名称:" + stopWatch.currentTaskName() +" 执行时间:" + stopWatch.getTotalTimeMillis());

   }
}

执行情况一:

执行情况二:

从上图可看出,list的add操作并非我们想要的结果。

3.如果非要用并行流怎么办

加锁吧。

javascript 复制代码
public class TestParallel {
    public static void main(String[] args) {
        StopWatch stopWatch = new StopWatch();
        List<Integer> list = new ArrayList<>();
        stopWatch.start("TaskOneName");
         Lock lock = new ReentrantLock();
        IntStream.range(0, 10000).parallel().forEach(adata->{
            lock.lock();
            try {
                list.add(adata);
            }finally {
                lock.unlock();
            }
        });
        stopWatch.stop();
        System.out.println("list size:" + list.size());
        System.out.println("当前任务名称:" + stopWatch.currentTaskName() +" 执行时间:" + stopWatch.getTotalTimeMillis());
 
    }
}

执行结果:

4.使用线程安全的ArrayList:

使用线程安全的ArrayList: CopyOnWriteArrayList

相关推荐
叼烟扛炮7 小时前
C++第二讲:类和对象(上)
数据结构·c++·算法·类和对象·struct·实例化
love530love9 小时前
精简版|Claude-HUD 插件介绍 + 一键安装教程
人工智能·windows·笔记
秋910 小时前
MySQL 8.0.46 全平台安装与配置详解(Windows/Linux/macOS)
linux·windows·mysql
善恶怪客11 小时前
LocalSend基本使用
windows
MegaDataFlowers11 小时前
206.反转链表
数据结构·链表
MengMeng_102312 小时前
win10 蓝牙连接音响没有声音设备选项
windows
CN-Dust12 小时前
【C++】while语句例题专题
数据结构·c++·算法
强殖装甲凯普13 小时前
处理Windows没有msi的默认打开方式
windows·安装·msi
mOok ONSC13 小时前
mysql9.0windows安装
windows·adb
T0uken14 小时前
基于 vcpkg 与 LLVM-MinGW 的 Qt6 静态链接开发方案
c++·windows·qt