为什么这个流不能并行运行?

时间:2016-06-05 19:05:25

标签: java parallel-processing java-stream

如何让它并行运行?我的输出是完全顺序的,并且在完成所有操作之前不会显示已用时间。这是我第一次尝试并行化流,所以我可能会错过其他人明显的东西。但是,与我查看的示例代码相比,我看不出有什么问题。

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));
    }

}

3 个答案:

答案 0 :(得分:2)

但它是平行的!试验一下:

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 ...

之后打印时间

答案 1 :(得分:0)

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

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

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

答案 2 :(得分:0)

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. 使用新主题(新Parallels())创建主题
  3. 使用 t.start()开始执行
  4. 使用 t.join()等待线程直到完成
  5. 如果你没有看到任何并发,请插入一个 Thread.sleep(),这会减慢线程的速度,并且会激活&#34; VM切换到另一个线程