2017-04-07 38 views
5
執行此任務paralell

我在Java併發新的,所以我問什麼是這樣執行操作的最佳方法:我有一個圖像中匹配的子圖像靜態方法如何Java8

。它看起來像:

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

該方法返回null如果沒有被匹配,否則返回匹配的點。

現在我有一個(大)圖像的40個不同的子圖像,我想要平行匹配。每一秒我都會得到一個新的(大)圖像,我需要一次又一次搜索這40個較小的圖像。我需要每次調用的返回值來匹配我主任務中匹配任務結束時的方法,以便我可以分析它。 此外我需要使用盡可能多的CPU內核來完成此任務。

我該如何做到這一點? 我已經閱讀了很多關於ExecutorService,Task,Runnable等的內容。大多數示例僅顯示如何在paralles中的控制檯上打印某些內容。我真的很困惑我應該在我的方案中採用哪種方式:如何傳遞值以及如何獲得結果?班級的佈局應該如何?此外,我不知道什麼是要走的路,如果我創建40個第二任務(這將需要一些時間來設置任務,對吧?)

代碼將是巨大的解釋吧:)

回答

4

使用CompletionService,更可能是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; 
    } 
} 

如果你想使用所有的CPU,你可能想改變你的ExecutorServiceExecutors.newWorkStealingPool()。儘管如此,小心!

+1

哇,這正是我一直在尋找!非常感謝你 :) –

0

你似乎正在尋找一個教程,如this

+3

這應該是一個評論 – Eugene

+1

無法寫入帶註釋<50聲譽.... –

+1

然後讓那些50個代表:)我其實並不知道這些......還是這是不好的一個回答,你可能會被拒絕投票。 – Eugene

0

您可以使用ExecutorService executorService = Executors.newFixedThreadPool(40);這將創建一個由40個線程組成的線程池。然後創建一個樣本類,如CompareImage extends Callable,然後創建CompareImage的40個對象添加到Collection。 然後撥打invokeAll()executorService對象。

List<Future<Point>> list = executorService.invokeAll(listOfCompareImage); 
2

我知道一個答案已被接受,但我想發佈一個更「流」的方法來使用java-8流。代碼要小得多,但應該工作得很好。

for(BufferedImage bigImage:bigImages){ 
    List<Point> matchingPoints = subImages.parallelStream().map((smallImage) -> match(smallImage, bigImage)).collect(Collectors.toList()); 
    //do whatever you want to do with matchingPoints, like adding to a bigger list 
}