Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to execute this paralell task in Java8

I'm new in Java concurrency, so i ask what is the best way to perform action like this:

I have a static method which matches a sub image within an image. It looks like that:

public static Point match(final BufferedImage subimage, final BufferedImage image)

The method returns null if nothing was matched, else it returns the Point of the match.

Now I have 40 different sub images for one (big) image, which I want to match in parallel. Each second I will get a new (big) image in which I need to search those 40 smaller images over and over again. I need the return values of each call to to match method at the end of the match task in my main task, so I can analyze it. Furthermore I need to use as many CPU cores as possible for this task.

How can I accomplish that? I have read a lot about ExecutorService, Task, Runnable and so on. Most examples only show how to print something on the console in paralles. I am really confused which way I should go in my scenario: How to pass the values and how to get the results? How should the layout of the class(es) look like? Also I have no idea what is the way to go if I create 40 tasks a second (it will take some time to setup the task, right?)

Code would be great to explain it :)

like image 349
Peter Winzer Avatar asked Apr 07 '17 10:04

Peter Winzer


People also ask

How do you run a task in parallel Java?

ExecutorService EXEC = Executors. newCachedThreadPool(); List<Callable<Result>> tasks = new ArrayList<Callable<Result>>(); for (final Object object: objects) { Callable<Result> c = new Callable<Result>() { @Override public Result call() throws Exception { return compute(object); } }; tasks.

How do you do parallel tasks?

Parallel tasks are split into subtasks that are assigned to multiple workers and then completed simultaneously. A worker system can carry out both parallel and concurrent tasks by working on multiple tasks at the same time while also breaking down each task into sub-tasks that are executed simultaneously.

Can Java run parallel?

You can execute streams in serial or in parallel. When a stream executes in parallel, the Java runtime partitions the stream into multiple substreams. Aggregate operations iterate over and process these substreams in parallel and then combine the results.


1 Answers

Use a CompletionService, more likely 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;
  }
}

If you want to use all the CPU, you probably want to change your ExecutorService to Executors.newWorkStealingPool(). Be careful with this though!

like image 159
Olivier Grégoire Avatar answered Oct 07 '22 21:10

Olivier Grégoire