繁体   English   中英

为什么该流不能并行运行?

[英]Why can't this stream run in parallel?

如何使它并行运行? 我的输出是完全顺序的,并且直到一切完成后才显示经过的时间。 这是我首次尝试并行化流,因此我可能会错过其他人显而易见的东西。 但是与我查看的示例代码相比,我看不出有什么问题。

public class Paralells {


    void run() {
        for (int i = 1; i<=1000; i++) System.out.println(i);
    }


    public static void main(String[] args) {

        ArrayList<Paralells> a = new ArrayList();

        a.add(new Paralells());
        a.add(new Paralells());
        a.add(new Paralells());
        a.add(new Paralells());
        a.add(new Paralells());

        long x = System.currentTimeMillis();
        a.parallelStream().forEach(p -> p.run());
        System.out.println("ELAPSED: " + (System.currentTimeMillis()-x));
    }

}

但这是并行的! 实验一下:

import java.util.*;
public class Paralells {

    private int id;
    public Paralells(int id) { this.id = id; }
    void run() {
        for (int i = 1; i<=1000; i++) System.out.println(id+" "+i);
    }


    public static void main(String[] args) {

        ArrayList<Paralells> a = new ArrayList();

        a.add(new Paralells(1));
        a.add(new Paralells(2));
        a.add(new Paralells(3));
        a.add(new Paralells(4));
        a.add(new Paralells(5));

        long x = System.currentTimeMillis();
        a.parallelStream().forEach(p -> p.run());
        //a.forEach(p -> p.run()); // sequential
        System.out.println("ELAPSED: " + (System.currentTimeMillis()-x));
    }
}

为每个元素设置一个id,并在打印消息时使用它。 您应该能够观察到消息是隔行扫描的。 与顺序版本进行比较(取消注释相应的行并注释平行版本)。

当然,时间是在一切完成之后收集的。 时间在forEach之后打印

我尝试了您的确切代码,并且确实可以并行执行。 我认为它可能看起来是顺序的,因为run()方法完成得如此之快,以至于流没有时间创建所有线程。

如果希望看到流实际上是并行运行的,请尝试在run()方法的循环内添加一个小的Thread.sleep(10)调用。

现在,对于第二部分,在完成所有操作之前不会打印经过的时间。 即使流是并行的,它仍然会阻塞。

import java.util.ArrayList;

public class Parallels implements Runnable {

    public void run() {
        for (int i = 1; i<=1000; i++) {
// uncomment this line, if you don't see concurrent execution
//            try { Thread.sleep(1); } catch (Exception e) {} 
            System.out.println(i);
    }   }


    public static void main(String[] args) {

        ArrayList<Thread> a = new ArrayList<>();

        for(int i=0; i<5; i++) a.add(new Thread(new Parallels()));

        long x = System.currentTimeMillis();

        for(Thread t : a) t.start();

        for(Thread t : a) try { 
            t.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("ELAPSED: " + (System.currentTimeMillis()-x));
    }
}
  1. 实现Runnable接口
  2. 使用new Thread(new Parallels())创建线程
  3. 使用t.start()开始执行
  4. 使用t.join()等待线程完成
  5. 如果看不到任何并发,请插入Thread.sleep() ,这会减慢线程速度并“促使” VM切换到另一个线程

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM