Ich verwende Threads in meiner Java-Anwendung, um parallel die Daten zu erhalten (mit Netzwerkaufrufen). Ich habe eine Methode (die nicht in einer Thread-Klasse ist), die einen Thread-Pool mit gegebener Größe (10-15 max) erstellt und sie für Netzwerkaufrufe verwendet, und ich rufe diese Methode mehrmals aus einer Schleife.Erstellen zu viele Threads in Java
Wenn ich diese Anwendung auf einem langsamen Computer (3GB RAM, Pentium-IV) ausführen, funktioniert alles gut, aber wenn ich es auf einem iMac (32GB RAM, i7 Prozessor) ausführen, erstellt es zu viele Threads, etwa 2500 manchmal und einen Speicherfehler auswerfen.
Ich vermute, dass JVM die fertigen Threads nicht zurück in den Pool zurückstellt, sobald sie fertig sind, daher werden neue Threads erstellt.
Und sogar auf dem iMac, wenn ich Thread.sleep (1000) halten; in der for-Schleife, die ich oben erwähnt habe, funktioniert alles gut. Erstellen von etwa 900 Threads.
nachfolgenden Code-Proben aus dieser Anwendung sind:
public ArrayList<String> getValuesForKeyFromMaps(String key, ArrayList<Meta> locations) throws InterruptedException, ExecutionException{
int threadNum = locations.size(); // 10-15 at max
ExecutorService executor = Executors.newFixedThreadPool(threadNum);
List<FutureTask<ArrayList<String>>> taskList = new ArrayList<FutureTask<ArrayList<String>>>();
for(final Meta location : locations){
FutureTask<ArrayList<String>> futureTask_1 = new FutureTask<ArrayList<String>>(new Callable<ArrayList<String>>() {
public ArrayList<String> call() throws Exception {
// service call
return getValues(key, location);
}
});
taskList.add(futureTask_1);
executor.execute(futureTask_1);
}
ArrayList<String> values = new ArrayList<String>();
// Wait until all results are available and combine them at the same time
for (int j = 0; j < threadNum; j++) {
FutureTask<ArrayList<String>> futureTask = taskList.get(j);
values.addAll(futureTask.get());
}
executor.shutdown();
return values;
}
Wenn ich das obige Verfahren unter Verwendung der unten for-Schleife auf iMac nennen, wirft es Speicherfehler, da seine Gewindegänge etwa 2500 zu schaffen. Aber funktioniert auf der langsameren Maschine gut.
Und mit dem folgenden Code, auf iMac funktioniert es gut mit etwa 900 Threads
for(String key : keySet){
getValuesForKeyFromMaps(key, metaMap.get(key));
Thread.sleep(200); //sleeping for 200ms
}
Wenn ich 1000ms Schlafzeit in der oben für die Schleife zu erhöhen, seine Erstellung nur 30-50 Fäden und die Anwendung funktioniert gut.
Wie kontrolliere ich maximale zulässige Threads in meiner Anwendung. Ich soll maximal 10-15 Threads zu gegebener Zeit erstellen/verwenden, aber Java schafft zu viele.
2500 oder sogar 900 Gewinde ist eine große Sache. Was willst du damit machen? –
siehe dies: http://stackoverflow.com/questions/763579/how-many-threads-can-a-java-vm-support –
Ich sehe nichts wie "Erstellen von etwa 900 Threads". Sie erstellen zuerst einen Executor mit einer Anzahl von Threads, die auf 'locations.size()' festgelegt sind. Anschließend durchlaufen Sie diese Speicherortsammlung und erstellen eine Aufgabe pro Speicherort und fügen diese zum Thread-Pool hinzu.Entweder ist diese Standortgröße viel mehr als Sie dachten, oder Sie erstellen nur 10-15 (max) Aufgaben. Und ... nebenbei ... erstelle den Thread-Pool außerhalb dieses Code-Snippets. – Seelenvirtuose