Hallo,
ich will eine langwierige Rechnung parallelisieren. Ich habe viel mit ExecutorService und den entsprechenden ThreadPools experimentiert. Aber so richtig bekomme ich damit nicht hin was ich will. Ich weiss vor allem nicht wie man den TreadPool sinnvoll steuert (aktive Threads schlafen legen usw.)
Ich habe mal ein kleines Codebeispiel geschrieben. Ich nutze int[] als Input und Integer als Resultat. Diese Datenstrukturen dienen nur als Beispiel.
Ich denke mit dem Codebeispiel wird klarer was ich vor habe:
ich will eine langwierige Rechnung parallelisieren. Ich habe viel mit ExecutorService und den entsprechenden ThreadPools experimentiert. Aber so richtig bekomme ich damit nicht hin was ich will. Ich weiss vor allem nicht wie man den TreadPool sinnvoll steuert (aktive Threads schlafen legen usw.)
Ich habe mal ein kleines Codebeispiel geschrieben. Ich nutze int[] als Input und Integer als Resultat. Diese Datenstrukturen dienen nur als Beispiel.
Ich denke mit dem Codebeispiel wird klarer was ich vor habe:
Java:
package experiment;
import java.util.HashMap;
import java.util.Map;
public class ParallelHelperExample {
public static void main(String[] args) {
Map<String, int[]> dataMap = new HashMap<String, int[]>();
dataMap.put("AcceleratorCollisionDataSet-2015-05-25", new int[] { 1, 2, 3 });
dataMap.put("AcceleratorCollisionDataSet-2015-05-26", new int[] { 4, 5, 6 });
dataMap.put("AcceleratorCollisionDataSet-2015-05-27", new int[] { 7, 8, 9 });
// ... typischerweise 200 dataSets
ParallelHelper helper = new ParallelHelper(dataMap) {
@Override
Integer calcResult(int[] data) {
return 0; // die Berechnung ist extremst kompliziert und langwierig (Stunden)
}
};
helper.start();
// danach sporadische Aufrufe von helper.getResult(mapKey). Der Wert von 'mapKey' ist nicht vorhersagbar
// und somti auch die Reihenfolge der Berechnung der Resultate nicht optimierbar
}
}
abstract class ParallelHelper {
final Map<String, Integer> resultMap = new HashMap<String, Integer>();
public ParallelHelper(Map<String, int[]> dataMap) {
// nutzt eine Art Threadpool, z.B. via ExecutorService
}
void start() {
// started die Berechnung fuer jedes key-value Paar in 'dataMap' ein Ergebnis via calcResult(...)
// speichert das Ergebnis in 'resultMap'
}
// calcResult muss von Nutzer von ParallelHelper implementiert werden
abstract Integer calcResult(int[] data);
int getResult(String mapKey) {
// schaut ob das Ergebnis fuer 'mapKey' bereits berechnet wurde
// muss das Ergebnis noch berechnet werden, nutzt ParallelHelper nun 100% der Rechenleistung um das Ergbnis fuer 'mapKey' zu generieren
// dazu muessen alle aktiven Threads im Pool die gerade Ergebnisse fuer andere 'mapKeys' berechnen 'schlafen gelegt' bzw. 'gestoppt' werden
// Anmerkung: es waere gut, wenn ParallelHelper hier die bereits laufenden Berechnungen nur anhalten und spaeter wieder fortsetzen
// koennte anstatt komplett stoppen und neu beginnen. Dies liegt daran, dass einzelne Berechnungen teilweise Stunden brauchen.
// Sonderfall: der gesuchte mapKey wird bereits von einem der aktiven Threads berechnet.
// In diesem Fall soll dieser eine Thread natuerlich weitermachen und nicht 'schlafen gelegt' werden ;)
// wurde das gesuchte Ergebnis berechnet sollten die vorher 'schlafen gelegten' bzw. 'gestoppten' Threads
// wieder automatisch weiterarbeiten bzw. 'neu gestartet' werden bis 'resultMap' vollstaendig gefuellt ist
return 0; // das gesuchte Ergebnis wird zurueckgegeben
}
}