2010-11-25 17 views
5

मैं एक जावा कार्यक्रम hava, इसके बारे में एक अनुभाग गहन गणना, इसजावा में कम्प्यूटेशनल गहन कोड सेगमेंट को मल्टीथ्रेड कैसे करें?

for i = 1 :512 
    COMPUTE INTENSIVE SECTION 
end 

मैं इसे multithread में विभाजित करना चाहते हैं की तरह है, यह तेजी से चलते समय करते हैं।

COMPUTE अंतर्निहित अनुभाग अनुक्रमिक-वार नहीं है। इसका मतलब है कि पहले i = 1 चलाना या i = 5 मुट्ठी एक ही है ...

क्या कोई मुझे इस बारे में एक भव्य मार्गदर्शिका दे सकता है। यह कैसे करना है? वास्तव में धन्यवाद! हैप्पी थैंक्सगिविंग! किसी भी जावा बहु सूत्रण ट्यूटोरियल पर

+1

"भव्य गाइड" करने के लिए इस उत्कृष्ट पुस्तक [अभ्यास में जावा संगामिति] (है http://www.javaconcurrencyinpractice.com/), ब्रायन गोएट्ज़ एट अल द्वारा। –

+1

http://download.oracle.com/javase/tutorial/essential/concurrency/forkjoin.html फोर्क/फ्रेमवर्क में शामिल हों सटीक रूप से उस मामले के लिए बनाया गया है (और अन्य, भी :-)। चेतावनी: केवल जेडीके 7। – helpermethod

+0

बीटीडब्ल्यू किसी को पता है कि ओडीकल जेडीके 7 के रिलीज संस्करण से पहले ट्यूटोरियल में जेडीके 7 लिंक क्यों रखता है? –

उत्तर

3

ध्वनि एक धागा पूल की तरह अच्छा होगा। असल में, आप एन अलग-अलग धागे के संग्रह को चाबुक करते हैं, फिर उन्हें लूप में अनुरोध करें। जब तक धागा उपलब्ध न हो तब तक अनुरोध ब्लॉक।

ThreadPool pool = Executors.newFixedThreadPool(10); // 10 threads in the pool 
ArrayList<Callable> collectionOfCallables = new ArrayList<Callable>(); 
for (...) { 
    Callable callable = new Callable<Foo>() { public Foo call() { COMPUTE INTENSIVE SECTION } } 
    collectionOfCallables.add(callable); 
} 

ArrayList<Future<Foo>> results = pool.invokeAll(collectionOfCallables); 

pool.awaitTermination(5, TimeUnit.MINUTES); // blocks till everything is done or 5 minutes have passed. 

भविष्य के साथ आपको वास्तव में समाप्ति का इंतजार करने की आवश्यकता नहीं है। भविष्य में परिणाम प्राप्त करें() को तब तक अवरुद्ध कर देगा जब तक संबंधित थ्रेड (या रद्द नहीं किया जाता)।

+0

आपको शायद Runtime.availableProcessors() आपके थ्रेड पूल के लिए एक अच्छा आकार मिल सकता है। इसका उपयोग आपकी मशीन के आकार पर निर्भर पूल आकार को गतिशील रूप से बदलने के लिए किया जा सकता है। –

+0

क्या हो रहा है इसके आधार पर, 1 थ्रेड प्रति प्रोसेसर जाने का सबसे अच्छा तरीका नहीं हो सकता है ... विशेष रूप से जब आप "हाइपर थ्रेडिंग" जैसे प्रोसेसर चाल लेते हैं। हालांकि प्रोसेसर गिनती निश्चित रूप से एक कारक होगी ... अच्छा बिंदु। –

3

देखो, या तो सरकारी एक:

या दूसरों से कुछ, जैसे:

5

आप Java Tutorial की Concurrency Trail पढ़ना चाहिए। विशेष रूप से Executors और Thread Pools आपके लिए प्रासंगिक होना चाहिए।

मूल रूप से, आप the Executors class में कारखाने तरीकों में से एक के माध्यम से एक थ्रेड पूल (जो एक Executor है) बना सकते हैं और इसे करने के लिए Runnable उदाहरणों सबमिट करें:

for(int i = 0; i < 512; i++){ 
    executor.execute(new Runnable(){public void run(){ 
     // your heavy code goes here 
    }}); 
} 
+1

यदि यह 'execors.newFixedThreadPool (Runtime.getRuntime()। GetAvailableProcessors()) का उपयोग करके एक गणना गहन कार्य है, क्योंकि निष्पादक थ्रेड पूल में थ्रेड की संख्या के लिए एक अच्छी शर्त है। –

0

शॉन पैट्रिक फ्लोयड के जवाब की तरह, लेकिन एक सा एक लैम्ब्डा अभिव्यक्ति के साथ कम वर्बोज़:

ExecutorService es = Executors.newCachedThreadPool(); 
for(int i = 0; i < 512; i++){ 
    es.execute(() -> { 
     // code goes here 
    }); 
} 
+0

तो, जावा 8 से यह संभव है। –

0

आप छोटे उप कार्य पुनरावर्ती करने के लिए अपने गहन कार्रवाई विभाजित कर सकते हैं, तो ForkJoinPool आप के लिए आदर्श है।

अपने सर्वर 8 core CPU साथ चल रहा है, तो आप पूल आकार सेट कर सकते के रूप में 8

ForkJoinPool forkJoinPool = new ForkJoinPool(8); 

या

आप Executor ServiceFixedThreadPool नीचे के रूप में Callable को गणना गहन कार्य को ले जाकर उपयोग कर सकते हैं

ExecutorService executorService = Executors.newFixedThreadPool(8); 

Future future = executorService.submit(new Runnable() { 
public void run() { 
    System.out.println("Your compute intensive task"); 
} 
}); 

future.get(); //returns null if the task has finished correctly. 

ForkJoinPool के साथ एक फायदा है। निष्क्रिय धागे blokcingQueue से व्यस्त धागे से नौकरियों चोरी करेंगे जहां आपके Runnable/Callable कार्यों को प्रस्तुत किया गया है।

जावा 8 Executors में एक और नई एपीआई कहा: newWorkStealingPool

आप सभी कार्यों को पूरा करने के लिए प्रतीक्षा करने की जरूरत है, उपयोग ExecutorService पर invokeAll() उपयोग कर सकते हैं।

उन्नत समवर्ती जावा 8 का उपयोग कर एपीआई के लिए Benjamin द्वारा इस article पर एक नज़र डालें

संबंधित मुद्दे