Ich möchte einen Cache-Thread-Pool erstellen, der jedoch als fester Thread fungiert. Zur Zeit habe ich diesen Code:Thread-Pool wird nicht skaliert
public class BackgroundProcesses {
public static void main(String[] args) throws InterruptedException, ExecutionException {
//ExecutorService threadPool2 = Executors.newCachedThreadPool();
ExecutorService threadPool = new ThreadPoolExecutor(2, 10, 180, TimeUnit.SECONDS, new LinkedBlockingQueue<>());
for (int i = 0; i < 800; i++) {
Callable<String> task = new Task();
threadPool.submit(task);
}
}
}
class Task implements Callable<String> {
@Override
public String call() throws Exception {
Thread.sleep(100);
System.out.println(Thread.currentThread().getName() + " is ready");
return "";
}
}
Wenn ich den Code ausführen ich Ausgabe:
pool-1-thread-1 is ready
pool-1-thread-2 is ready
pool-1-thread-1 is ready
pool-1-thread-2 is ready
...
Bedeutung nur 2 Fäden machen die ganze Arbeit und keine neuen Worker-Threads werden in den Pool aufgenommen. Sollte der Threadpool nicht mehr Threads erzeugen, wenn Aufgaben in der Warteschlange stehen (in meinem Fall bis zu 10)?
Ich möchte nicht Executors.newCachedThreadPool()
verwenden, weil es praktisch keine obere Grenze für maximale Threads hat und es hat corePoolSize
0. Ich möchte immer einige Threads bereit für bessere Reaktionsfähigkeit haben.
----- bearbeiten 1 -----
Danke Aleksey für die Antwort. Wenn ich die Warteschlangenkapazität so anwähle, dass sie sich wie erwartet verhält, habe ich jetzt ein neues Problem.
Die Anzahl der Hintergrundaufgaben ist sehr unterschiedlich. Meistens 0, kann aber für kurze Zeit bis zu 50 gleichzeitige Aufgaben ausführen. Was wäre ein effizienter Weg, damit umzugehen? Beachten Sie, dass die meisten Hintergrundaufgaben nur von kurzer Dauer sind (< 1s), aber auch ein paar langlebige Aufgaben (> 1min).
Wenn ich meinen Threadpool wie folgt aufgebaut:
ExecutorService threadPool = new ThreadPoolExecutor(2, 10, 180, TimeUnit.SECONDS, new LinkedBlockingQueue<>(10));
Ich werde höchstwahrscheinlich RejectedExecutionException mit Spitzenauslastung bekommen. Allerdings, wenn ich aufgebaut wie dieser thread:
ExecutorService threadPool = new ThreadPoolExecutor(2, 10, 180, TimeUnit.SECONDS, new LinkedBlockingQueue<>(200));
Dann keine neuen Worker-Threads werden jemals da die Warteschlange wird nicht max out hinzugefügt werden.
Die CPU hat mindestens 4 Kerne, das wäre meiner Meinung nach verschwenderisch. Und meistens gibt es überhaupt keine Hintergrundaufgaben (80% der Betriebszeit), also wäre es meiner Meinung nach auch eine Verschwendung eines festen Thread-Pools.
Vielen Dank für das Aufräumen. Aber jetzt bekomme ich RejectedExecutionException (Poolgröße = 10, aktive Threads = 10, wartende Tasks = 10), da die Warteschlange voll ist und alle aktiven Threads auch aufgebraucht sind. –