2016-09-27 4 views
0

Ich habe eine Liste von Hunderttausenden von Aufgaben, die erledigt werden müssen (in beliebiger Reihenfolge). Es dauert mehrere Stunden, um sie alle zu durchlaufen. Ich denke, eine gute Möglichkeit, es zu beschleunigen, wäre es, es parallel laufen zu lassen.Ich versuche, Schleifen-Iterationen parallel in Groovy auszuführen - Fehler erhalten

Hier ist eine minimale Wiedergabe des Codes, der feinen Single-Threaded und arbeitet ist:

doTask = { more -> 
    println("Start") 
    sleep 10000 // sleep 10 seconds 
    println("Finish") 
} 

(1..3).each{ more -> doTask(more) } 

ich keine Erfahrung mit Groovy haben so diese funktionelle Syntax ist mir ein bisschen fremd ... aber ich fand eine Menge von Fragen auf SO, wo die Menschen vorgeschlagen, dass Sie diese Seite überprüfen:

http://groovy.codehaus.org/Concurrency+with+Groovy

linkrot aufgetreten ist - die Seite existiert nicht mehr, aber ich habe ein Archiv finden es hier:

https://web.archive.org/web/20150102212441/http://groovy.codehaus.org/Concurrency+with+Groovy

Ich habe versucht, die Beispiele von dieser Seite anzupassen und damit endete:

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)} } 

Wenn ich es hier laufen: http://groovyconsole.appspot.com/

ich diesen Fehler:

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) 

Was ist los? Habe ich die Syntax irgendwie durcheinander gebracht? Verwende ich eine API? Ist das vielleicht nur eine Einschränkung dieser Website?

+0

Sie versuchen, Threads auf VM zu erstellen, die sich auf einem anderen Computer befinden. Dies kann leicht dazu verwendet werden, die Site herunterzufahren, sodass sie die Berechtigungen für webconsole entfernt haben. Versuchen Sie es lokal auszuführen. –

Antwort

1

Nein, dieser Code läuft für mich gut ... die Ausnahme liegt wahrscheinlich daran, dass die von Ihnen verwendete Appspot-Webkonsole keine Multithread-Anwendungen ausführen lässt.

Download Groovy und führen Sie es mit der Groovy Console, es wird gut funktionieren.

Aber hier ist ein Vorschlag für Ihren Code ein wenig zu vereinfachen:

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) } } 

In Groovy, irgendetwas zwischen geschweiften Klammern ist ein Verschluss Sie zum Pool einreichen können.

So pool.submit { /* any code here to run async */ } funktioniert.

+0

Danke! Ich nahm an, dass es wahrscheinlich einen Weg gab, diese "Aufschub" -Funktion einfach zu entfernen und zu entfernen, aber ich hatte größere Bedenken, wie ich zuerst Ausnahmen bekommen konnte. Ich habe Groovy heruntergeladen und den Code in der Konsole ausgeführt. Es funktionierte! (Mein Code läuft tatsächlich auf einem kopflosen Server ist der einzige Grund, warum ich Groovy nicht bereits installiert habe.) – ArtOfWarfare

+0

Sie könnten sogar den Pool vermeiden, indem Sie Java 8 'parallelStream' verwenden:' (1..3) .parallelStream(). map {more -> doTask (more)} .toArray() '(toArray() ist notwendig, weil' map() 'faul ist). – Renato

+0

Nicht sicher, welche Version von Java/Groovy verwendet wird (es gibt eine komplizierte Menge von Layern für mich, um die tatsächliche VM zu erreichen, auf der ich arbeite ... sie ist in eine ausführbare Datei in einer ausführbaren Datei auf einem entfernten Rechner eingebettet). .). Ich versuche bei APIs zu bleiben, die es schon immer gibt, um die Wahrscheinlichkeit zu minimieren, versehentlich etwas zu verwenden, das zu neu ist ... – ArtOfWarfare

Verwandte Themen