मेरे पास सैकड़ों हजारों कार्यों की एक सूची है जिन्हें करने की आवश्यकता है (किसी भी क्रम में)। इन सब से गुजरने में कई घंटे लग जाते हैं। मुझे लगता है कि इसे तेज करने का एक अच्छा तरीका इसे समानांतर में चलाने का प्रयास करना होगा।
यहां कोड का एक न्यूनतम पुनरुत्पादन है जो सिंगल थ्रेडेड है और ठीक काम करता है:
doTask = { more ->
println("Start")
sleep 10000 // sleep 10 seconds
println("Finish")
}
(1..3).each{ more -> doTask(more) }
मुझे ग्रोवी के साथ कोई पूर्व अनुभव नहीं है इसलिए यह कार्यात्मक वाक्यविन्यास मेरे लिए थोड़ा अलग है ... लेकिन मुझे SO पर बहुत सारे प्रश्न मिले जहां लोगों ने सुझाव दिया कि आप इस पृष्ठ को देखें:
http://groovy.codehaus.org/Concurrency+with+Groovy
लिंक्रोट हुआ है - वह पृष्ठ अब मौजूद नहीं है, लेकिन मुझे इसका एक संग्रह यहां मिला है:
https://web.archive.org/web/20150102212441/http://groovy.codehaus.org/Concurrency+with+Groovy
मैंने उस पृष्ठ से उदाहरणों को अपनाने की कोशिश की और इसके साथ समाप्त हुआ:
import java.util.concurrent.*
pool = Executors.newFixedThreadPool(3)
defer = {c -> pool.submit(c as Callable) }
doTask = { more ->
println("Start")
sleep 10000 // sleep 10 seconds
println("Finish")
}
(1..3).each{ more -> defer{doTask(more)} }
जब मैं इसे यहां चलाता हूं: http://groovyconsole.appspot.com/
मुझे यह त्रुटि मिलती है:
java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "modifyThreadGroup")
at Script1$_run_closure1.doCall(Script1.groovy:5)
at Script1$_run_closure3.doCall(Script1.groovy:12)
at Script1.run(Script1.groovy:12)
क्या चल रहा है? क्या मैंने किसी तरह वाक्यविन्यास को गड़बड़ कर दिया है? क्या मैं एपीआई का दुरुपयोग कर रहा हूं? क्या यह शायद उस वेबसाइट की एक सीमा है?
1 उत्तर
नहीं, यह कोड मेरे लिए ठीक चलता है ... अपवाद शायद इसलिए है क्योंकि आप जिस ऐपस्पॉट वेब कंसोल का उपयोग कर रहे हैं वह बहु-थ्रेडेड एप्लिकेशन को चलाने की अनुमति नहीं देता है।
ग्रूवी डाउनलोड करें और इसे ग्रोवी कंसोल के साथ चलाएं, यह ठीक काम करेगा।
लेकिन आपके कोड को थोड़ा सा सरल बनाने के लिए यहां एक सुझाव दिया गया है:
import java.util.concurrent.Callable
import java.util.concurrent.Executors
pool = Executors.newFixedThreadPool( 3 )
doTask = { more ->
println "Start"
sleep 10000 // sleep 10 seconds
println "Finish"
}
( 1..3 ).each { more -> pool.submit { doTask( more ) } }
ग्रूवी में, घुंघराले ब्रेसिज़ के बीच कुछ भी एक क्लोजर है जिसे आप पूल में जमा कर सकते हैं।
तो pool.submit { /* any code here to run async */ }
काम करता है।
defer
फ़ंक्शन को आसानी से हटाने और निकालने का एक तरीका था, लेकिन मुझे इस बारे में बड़ी चिंता थी कि मुझे पहले से निपटने के लिए अपवाद कैसे मिल रहे हैं। मैंने ग्रोवी डाउनलोड किया और कंसोल में कोड चलाया। इसने काम कर दिया! (मेरा कोड वास्तव में एक हेडलेस सर्वर पर चल रहा है, यही एकमात्र कारण है कि मैंने पहले से ही ग्रोवी स्थापित नहीं किया है।)
parallelStream
: ( 1..3 ).parallelStream().map { more -> doTask( more ) }.toArray()
(toArray() का उपयोग करके पूल से भी बच सकते हैं क्योंकि map()
आलसी है)।
संबंधित सवाल
नए सवाल
multithreading
बहु-थ्रेडिंग के बारे में प्रश्नों के लिए, निष्पादन की कई समवर्ती धाराओं (आमतौर पर थ्रेड्स के रूप में संदर्भित) का उपयोग करके कंप्यूटर या प्रोग्राम को समवर्ती या अतुल्यकालिक रूप से कार्य करने की क्षमता।