Java8

2017-04-07 9 views
5
में इस समानांतर कार्य निष्पादित करने के लिए कैसे

मैं जावा संगामिति में नए हूँ, इसलिए मैं पूछ इस तरह कार्रवाई करने के लिए सबसे अच्छा तरीका है क्या:Java8

मैं एक स्थिर तरीका है जिसके एक छवि के भीतर एक उप छवि से मेल खाता है । ऐसा नहीं है कि तरह लग रहा है:

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

विधि अशक्त वापस लौट आता है कुछ भी नहीं मिलान किया गया था, और यह मैच के प्वाइंट देता है।

अब मेरे पास एक (बड़ी) छवि के लिए 40 अलग-अलग उप छवियां हैं, जिन्हें मैं समानांतर में मिलान करना चाहता हूं। प्रत्येक सेकेंड में मुझे एक नई (बड़ी) छवि मिल जाएगी जिसमें मुझे उन 40 छोटी छवियों को बार-बार खोजना होगा। मुझे अपने मुख्य कार्य में मिलान कार्य के अंत में विधि से मिलान करने के लिए प्रत्येक कॉल के वापसी मूल्यों की आवश्यकता है, इसलिए मैं इसका विश्लेषण कर सकता हूं। इसके अलावा मुझे इस कार्य के लिए जितना संभव हो उतने सीपीयू कोर का उपयोग करने की आवश्यकता है।

मैं इसे कैसे पूरा कर सकता हूं? मैंने निष्पादक सेवा, कार्य, रननेबल आदि के बारे में बहुत कुछ पढ़ा है। अधिकांश उदाहरण केवल दिखाते हैं कि कंसोल पर कुछ कंसोल पर प्रिंट कैसे करें। मैं वास्तव में उलझन में हूं कि मुझे अपने परिदृश्य में किस तरह जाना चाहिए: मूल्यों को कैसे पास किया जाए और परिणाम कैसे प्राप्त करें? कक्षा (एस) का लेआउट कैसा दिखना चाहिए? इसके अलावा मुझे नहीं पता है कि अगर मैं 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; 
    } 
} 

आप सभी सीपीयू उपयोग करना चाहते हैं, तो आप शायद अपने 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

मैं जानता हूँ कि एक जवाब पहले से ही स्वीकार किया गया है, लेकिन मैं इस का उपयोग कर जावा-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 
} 
संबंधित मुद्दे