java 8并行流需要更多时间

时间:2017-05-08 17:12:07

标签: java concurrency parallel-processing java-8

我正在尝试了解java 8并行流。我写了下面的代码,首先使用Executor,然后使用并行流。 看起来平行流需要两倍(10秒)的时间与Executor接近(5秒)。在我看来,并行流也应该表现出类似的性能。任何想法为什么并行流需要两倍的时间? 我的电脑有8个核心。

host

1 个答案:

答案 0 :(得分:5)

解释很简单。您有8个核心,因此parallelStream()通常可以并行处理8个线程中的工作。他们都立即抓住任务,他们都睡了5秒钟。然后其中一个接受下一个(第9个)任务,它再睡5秒钟。然后完成处理。这意味着约5秒(8个线程)+ 5秒(1个线程)=总共10秒。但让我们看看这一点。我会略微修改你的代码:

 public static int processUrl(String url) {

    try {
        Thread.sleep(5000);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    System.out.println("T[" + Thread.currentThread().getId() + "] finished @[" + System.currentTimeMillis() / 1000 + "]");
    return url.length();
}

使用并行流,您可以获得类似于以下内容的输出:

T[1] finished @[1494267500]
T[12] finished @[1494267500]
T[17] finished @[1494267500]
T[13] finished @[1494267500]
T[14] finished @[1494267500]
T[16] finished @[1494267500]
T[11] finished @[1494267500]
T[15] finished @[1494267500]
T[12] finished @[1494267505]
36
10

请注意,相同的线程T [12]完成任务两次,并在完成8个任务的第一轮'后5秒完成。

使用线程执行程序,您创建了100个线程。因此,9个线程各占一个任务,执行时间约为5秒,因为线程池不会耗尽:

T[14] finished @[1494267783]
T[11] finished @[1494267783]
T[19] finished @[1494267783]
T[17] finished @[1494267783]
T[12] finished @[1494267783]
T[16] finished @[1494267783]
T[13] finished @[1494267783]
T[15] finished @[1494267783]
T[18] finished @[1494267783]
36
5

请注意,此处没有具有相同ID-s的线程。 (这是 NOT 建议为固定池选择通用线程数:-)我只是详细说明你的实际问题。)

试用调度程序并只分配8个线程:

ExecutorService executorService = Executors.newFixedThreadPool(8);

然后执行时间可能大致相同,因为线程池将耗尽。如果URL-s只是8而不是9,您会注意到类似的性能。

OF COURSE 无法保证此代码在不同环境中的行为相同。