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

यहां कोड का एक न्यूनतम पुनरुत्पादन है जो सिंगल थ्रेडेड है और ठीक काम करता है:

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)

क्या चल रहा है? क्या मैंने किसी तरह वाक्यविन्यास को गड़बड़ कर दिया है? क्या मैं एपीआई का दुरुपयोग कर रहा हूं? क्या यह शायद उस वेबसाइट की एक सीमा है?

0
ArtOfWarfare 27 सितंबर 2016, 20:42
आप VM पर थ्रेड बनाने की कोशिश कर रहे हैं जो किसी अन्य मशीन पर है - जिसका उपयोग साइट को नीचे लाने के लिए आसानी से किया जा सकता है, इसलिए उन्होंने वेब कंसोल के लिए अनुमतियां हटा दीं। इसे स्थानीय रूप से चलाने का प्रयास करें।
 – 
Filip Malczak
27 सितंबर 2016, 21:00

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 */ } काम करता है।

3
Renato 27 सितंबर 2016, 21:10
धन्यवाद! मुझे लगा कि शायद उस defer फ़ंक्शन को आसानी से हटाने और निकालने का एक तरीका था, लेकिन मुझे इस बारे में बड़ी चिंता थी कि मुझे पहले से निपटने के लिए अपवाद कैसे मिल रहे हैं। मैंने ग्रोवी डाउनलोड किया और कंसोल में कोड चलाया। इसने काम कर दिया! (मेरा कोड वास्तव में एक हेडलेस सर्वर पर चल रहा है, यही एकमात्र कारण है कि मैंने पहले से ही ग्रोवी स्थापित नहीं किया है।)
 – 
ArtOfWarfare
27 सितंबर 2016, 21:19
आप जावा 8 के parallelStream: ( 1..3 ).parallelStream().map { more -> doTask( more ) }.toArray() (toArray() का उपयोग करके पूल से भी बच सकते हैं क्योंकि map() आलसी है)।
 – 
Renato
27 सितंबर 2016, 21:22
सुनिश्चित नहीं है कि जावा/ग्रोवी के किस संस्करण का उपयोग किया जा रहा है (मेरे द्वारा चलाए जा रहे वास्तविक वीएम तक पहुंचने के लिए मेरे लिए कई जटिल परतें हैं ... ) मैं उन एपीआई के साथ रहने की कोशिश कर रहा हूं जो हमेशा के लिए आस-पास रहे हैं ताकि गलती से कुछ नया उपयोग करने की संभावना कम हो सके ...
 – 
ArtOfWarfare
27 सितंबर 2016, 21:50