并行流

并行流

串行流的操作是在单线程上执行的,

而并行流的操作是在多线程上并行执行的。

所以并行流的执行效率会更高,它是由多个线程同时操作一个流对象。

Collection接口两个默认方法说明
Stream stream()得到一个串行流
Stream parallelStream()得到一个并行流

这两个方法都是返回Stream对象,说明它们在功能的使用上是没差别的。唯一的差别就是流内部处理的时候一个是单线程处理和一个是多线程的处理。

串行流转换为并行流

只需要在流上调用一下无参数的parallel方法,那么当前流即可变身成为支持并行操作的流,

返回值仍然为Stream类型。

S parallel()
Stream的父接口中定义了一个parallel()方法,可以将一个串行流转成并行流,转换后与之前的流是同一个流。

直接获取并行流

在通过集合获取流时,也可以直接调用parallelStream方法来直接获取支持并行操作的流。方法定义为:

 default Stream parallelStream()  获取支持并行操作的流。

例如:

public class DemoParallel {
    public static void main(String[] args) {

        List<String> list = Arrays.asList("张无忌","周芷若","赵敏","张强","张三丰");

        Stream<String> stream = list.stream();  //串行
        
        //转成一个并行流
        Stream<String> parallel = stream.parallel();  //并行
        
        //直接获取并行流
        //Stream<String> stringStream = list.parallelStream();  //并行

        System.out.println(stream == parallel);
    }

}

并行流的分析

案例说明:

1) 创建一个测试类,声明一个全局ArrayList<Integer>

2) 创建init()方法,使用@Before注解,在每个测试方法运行前执行

3) 循环向集合中添加100个数

4) 写测试testStream()串行流的方法,将上面的集合调用stream()方法转成串行流,再调用forEach方法输出每个元素的值和处理当前线程的名字。

5) 写测试testParallel()并行流的方法,将上面的集合调用parallelStream()方法转成并行流,再调用forEach方法输出每个元素的值和当前线程的名字。

6) 查看运行结果可以得知,并行流中同时有多个线程在处理,不是按顺序处理的,而串行流中只有一个线程在依次处理。

案例代码:

public class Test {

//1)    创建一个测试类,声明一个全局ArrayList<Integer>

    ArrayList<Integer> nums = new ArrayList<>();


//2)    创建init()方法,使用@Before注解,在每个测试方法运行前执行

    @Before

    public void init() {

//3)    循环向集合中添加100个数

        for (int i = 0; i < 100; i++) {

            nums.add(i);
        }
    }

//4)    写测试testStream()串行流的方法,将上面的集合调用stream()方法转成串行流,再调用forEach方法输出每个元素的值和处理当前线程的名字。

    @Test

    public void testStream() {

        Stream<Integer> stream = nums.stream();

        stream.forEach(s -> System.out.println(s + "---" + Thread.currentThread().getName()));

    }

//5)    写测试testParallel()并行流的方法,将上面的集合调用parallelStream()方法转成并行流,再调用forEach方法输出每个元素的值和当前线程的名字。

    @Test
    public void testParallel() {

        Stream<Integer> stream = nums.parallelStream();

        stream.forEach(s -> System.out.println(s + "---" + Thread.currentThread().getName()));

    }

//6)    查看运行结果可以得知,并行流中同时有多个线程在处理,不是按顺序处理的,而串行流中只有一个线程在依次处理。

}

//使用并行流需要考虑几点:

//1)    并行流只是做到不浪费CPU,假如本身电脑CPU的工作量就很大,用并行流并不能起到很好的效果。

//2)    不要在多线程中使用并行流,多线程都抢着使用CPU是不会有太多的提升效果的,反而还会加大线程切换开销

//3)    并行流操作会带来不确定性,请确保流中每个元素是无状态且没有关联的

阅读更多
文章标签: 并行流
个人分类: Java8
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭