如何在Java8中执行此并行任务

Pet*_*zer 5 java concurrency multithreading java-8

我是Java并发的新手,所以我问这样做的最佳方法是什么:

我有一个静态方法,匹配图像中的子图像.它看起来像这样:

public static Point match(final BufferedImage subimage, final BufferedImage image)
Run Code Online (Sandbox Code Playgroud)

如果没有匹配,则该方法返回null,否则返回匹配的Point.

现在我有一个(大)图像的40个不同的子图像,我想要并行匹配.每一秒我都会得到一个新的(大)图像,我需要一遍又一遍地搜索这40个较小的图像.我需要每个调用的返回值来匹配我的主任务中匹配任务结束时的方法,所以我可以分析它.此外,我需要为此任务使用尽可能多的CPU内核.

我怎么能做到这一点?我已经阅读了很多关于ExecutorService,Task,Runnable等的内容.大多数示例仅显示如何在控制台上以平行方式打印内容.我真的很困惑我应该在我的场景中采用哪种方式:如何传递值以及如何获得结果?这个类的布局应该如何?另外,如果我每秒创建40个任务,我不知道该怎么办(设置任务需要一些时间,对吧?)

代码很好解释它:)

Oli*_*ire 4

使用 a CompletionService,更有可能使用 a ExecutorCompletionService

class Matcher {
  ExecutorService threadPool = Executors.newCachedThreadPool();
  private List<BufferedImage> subimages; // populate it yourself
  public static Point match(BufferedImage subimage, BufferedImage image) {
    // Your implementation
  }
  public List<Point> match(BufferedImage image) {
    CompletionService<Point> completionService = new ExecutorCompletionService(threadPool);
    int size = subimages.size();
    List<Point> results = new ArrayList<>(size);
    for (BufferedImage subimage: subimages) {
      completionService.submit(()->match(subimage, image));
    }
    for (int i = 0; i < size; i++) {
      Point point = completionService.take().get();
      if (point != null) {
        results.add(point);
      }
    }
    return results;
  }
}
Run Code Online (Sandbox Code Playgroud)

如果您想使用所有 CPU,您可能需要将您的更改ExecutorServiceExecutors.newWorkStealingPool(). 不过要小心这一点!