Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Java中并行执行for each循环中的语句?_Java_Multithreading_Concurrency_Parallel Processing - Fatal编程技术网

如何在Java中并行执行for each循环中的语句?

如何在Java中并行执行for each循环中的语句?,java,multithreading,concurrency,parallel-processing,Java,Multithreading,Concurrency,Parallel Processing,我有一段代码如下所示: public List<Restaurant> getAllRestaurants() { List<Restaurant> restaurants = getRestaurants().subList(0, 7); // This takes 234 ms to execute on average. // There are 7 items in the restaurants list for (Restau

我有一段代码如下所示:

public List<Restaurant> getAllRestaurants() {
    List<Restaurant> restaurants = getRestaurants().subList(0, 7); // This takes 234 ms to execute on average.    

    // There are 7 items in the restaurants list
    for (Restaurant restaurant : restaurants) {
        PlacesAPIResponse response = callGooglePlacesAPI(restaurant); // A call to the Google API should take 520ms for a given restaurant
        restaurant.setRating(response.getRating());
    }
    return restaurants;
}
long startTime = System.currentTimeMillis();
restaurants.parallelStream().forEach(restaurant -> {
    PlacesAPIResponse response = callGooglePlacesAPI(restaurant);
    restaurant.setRating(response.getRating());
});
long endTime = System.currentTimeMillis();
System.out.println("Calling Google Places API took " + (endTime - startTime) + " milliseconds");
这似乎是在为每个餐厅并行调用GooglePlacesAPI,但现在每次调用GooglePlacesAPI似乎都要花费越来越多的时间。以下是我的时间戳的输出:

getRestaurants() took 234 milliseconds
Took 335 milliseconds to call Google Places API for Restaurant 1
Took 337 milliseconds to call Google Places API for Restaurant 2
Took 671 milliseconds to call Google Places API for Restaurant 3
Took 742 milliseconds to call Google Places API for Restaurant 4
Took 1086 milliseconds to call Google Places API for Restaurant 5
Took 1116 milliseconds to call Google Places API for Restaurant 6
Took 1470 milliseconds to call Google Places API for Restaurant 7
Calling Google Places API took 1473 milliseconds
getRestaurants() took 234 milliseconds
Took 464 milliseconds to call Google Places API for Restaurant 1
Took 575 milliseconds to call Google Places API for Restaurant 2
Took 452 milliseconds to call Google Places API for Restaurant 3
Took 420 milliseconds to call Google Places API for Restaurant 4
Took 414 milliseconds to call Google Places API for Restaurant 5
Took 444 milliseconds to call Google Places API for Restaurant 6
Took 422 milliseconds to call Google Places API for Restaurant 7
Calling Google Places API took 1757 milliseconds
1734ms
比我预期的
754ms
大得多。我尝试了并行流以及ExecutorService来同时调用GooglePlacesAPI,但似乎无法获得所需的响应时间。谁能给我指出正确的方向吗?谢谢

编辑:以下是我在ExecutorService上尝试的内容,根据本文:

以下是我的时间戳的输出:

getRestaurants() took 234 milliseconds
Took 335 milliseconds to call Google Places API for Restaurant 1
Took 337 milliseconds to call Google Places API for Restaurant 2
Took 671 milliseconds to call Google Places API for Restaurant 3
Took 742 milliseconds to call Google Places API for Restaurant 4
Took 1086 milliseconds to call Google Places API for Restaurant 5
Took 1116 milliseconds to call Google Places API for Restaurant 6
Took 1470 milliseconds to call Google Places API for Restaurant 7
Calling Google Places API took 1473 milliseconds
getRestaurants() took 234 milliseconds
Took 464 milliseconds to call Google Places API for Restaurant 1
Took 575 milliseconds to call Google Places API for Restaurant 2
Took 452 milliseconds to call Google Places API for Restaurant 3
Took 420 milliseconds to call Google Places API for Restaurant 4
Took 414 milliseconds to call Google Places API for Restaurant 5
Took 444 milliseconds to call Google Places API for Restaurant 6
Took 422 milliseconds to call Google Places API for Restaurant 7
Calling Google Places API took 1757 milliseconds

这种方法的响应时间仍然是
234ms+1757ms
,而不是
234ms+575ms
,我不明白为什么

这里最好使用executorService,并将任务作为单独的Runnable()提供给它们


或者您可以在此处使用Future。

这里最好使用executorService,并将任务作为单独的Runnable()提供给他们


或者你可以在这里使用Future。

我想你的瓶颈是连接到internet或Google Places服务器,而不是你的循环。服务器会识别相同的IP地址,因此会将您的请求排队,以保护自身免受拒绝服务攻击。 这意味着您的循环并行运行,但internet请求堆积在服务器上,这就是为什么每个请求在得到响应和返回之前花费的时间越来越多。
为了避免这种情况,你需要一个机器人网络(从不同的计算机发送每个查询),或者Google Places会为你出售一个特殊的并行请求连接。

我想你的瓶颈是与internet或Google Places服务器的连接,而不是你的循环。服务器会识别相同的IP地址,因此会将您的请求排队,以保护自身免受拒绝服务攻击。 这意味着您的循环并行运行,但internet请求堆积在服务器上,这就是为什么每个请求在得到响应和返回之前花费的时间越来越多。

为了避免这种情况,您需要一个机器人网络(从不同的计算机发送每个查询),或者Google Places可能会为并行请求向您出售一个特殊连接。

这是很久以前的事了,但我想原因在于您选择的线程池大小。线程池大小为2意味着只能并行执行两个作业。剩余的作业将排队,直到释放线程。因此,您执行Google Places API的计算结果类似于
max(464+452+414+422575+420+444)=max(1752149)=1752
,这与实际值非常接近。这一点解释得很好。

这是很久以前的事了,但我想原因在于您选择的线程池大小。线程池大小为2意味着只能并行执行两个作业。剩余的作业将排队,直到释放线程。因此,执行Google Places API的计算结果类似于
max(464+452+414+422575+420+444)=max(1752149)=1752
,接近实际值。这一点解释得很好。

请参阅我的编辑。我解释了我对ExecutorService做了什么,但它仍然没有给我想要的响应时间。然后看起来@Chris是对的,Google让你的请求保持有序。你可以创建一个只在一个线程上运行的ExecutorService。是的,这是正确的路径,但仅仅说“执行者服务”只是一个开始,不是一个完整的答案。请参阅我的编辑。我解释了我对ExecutorService做了什么,但它仍然没有给我想要的响应时间。然后看起来@Chris是对的,Google让你的请求保持有序。你可以创建一个只在一个线程上运行的ExecutorService。是的,这是正确的途径,但仅仅说“执行者服务”只是一个开始,不是一个全面的答案。有趣的是,我没有想到这一点。我怎样才能测试这是否真的发生了,而不是我的循环出错了?@Warren刚刚打印了startTime。如果所有查询几乎同时开始,则循环是并行的。但如果以下请求仅在前一个请求完成后启动,则循环是连续的。您可以使用thread.currentThread().getId()打印线程Id。如果所有ID都相同,那么它是顺序的,如果它们都不同,那么它是并行的。谢谢Chris。是的,所有请求的启动时间都相同,线程ID也不同。所以看起来我的请求是并行发生的,谷歌正在排队等待请求。@warrencasta你可以通过将我的条目标记为已接受答案并投票来感谢我。那太好了,因为我刚从stackoverflow开始,需要每一点。在做了进一步的分析之后,谷歌看起来并没有限制我的请求。我用我开发的本地机器上的另一个API替换了对GooglePlaceDetailsAPI的调用,我看到了同样的行为。如果我知道发生了什么,我会把它贴在这里。有趣的是,我没想到。我怎样才能测试这是否真的发生了,而不是我的循环出错了?@Warren刚刚打印了startTime。如果所有查询几乎同时开始,则循环是并行的。但如果以下请求仅在前一个请求完成后启动,则循环是连续的。您可以使用thread.currentThread().getId()打印线程Id。如果所有ID都相同,那么它是顺序的,如果它们都不同,那么它是并行的。谢谢Chris。是的,所有请求的启动时间都相同,线程ID也不同。所以看起来我的请求是并行发生的,谷歌正在排队等待请求。@warrencasta你可以通过将我的条目标记为已接受答案并投票来感谢我。那太好了,