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

相关推荐
历程里程碑2 小时前
双指针1:移动零
大数据·数据结构·算法·leetcode·elasticsearch·搜索引擎·散列表
甘露s2 小时前
Redis 核心:概念理解与五大数据结构
数据结构·数据库·redis
苦藤新鸡2 小时前
39.判断对称二叉树
数据结构·力扣
多米Domi0112 小时前
0x3f 第41天 setnx的分布式锁和redission,白天写项目书,双指针
数据结构·分布式·python·算法·leetcode·缓存
鱼跃鹰飞3 小时前
LeetCode热题100:5.最长回文子串
数据结构·算法·leetcode
tobias.b3 小时前
408真题解析-2010-10-数据结构-快速排序
java·数据结构·算法·计算机考研·408真题解析
历程里程碑3 小时前
Linux 4 指令结尾&&通过shell明白指令实现的原理
linux·c语言·数据结构·笔记·算法·排序算法
tobias.b3 小时前
408真题解析-2010-11-数据结构-基础排序算法特征
数据结构·算法·排序算法·计算机考研·408真题解析
万象.6 小时前
redis数据结构set和zset的基本指令
数据结构·数据库·redis