2016-06-15 13 views
3
ExecutorService threadPool = Executors.newFixedThreadPool(N); 

for (Runnable task : tasks) { 
    threadPool.execute(task); 
} 

Ich bin ein bisschen neu zu Multithreading. Diese Frage habe ich kürzlich in einem Interview gestellt. Kann mir jemand bei der Lösung und einer klaren Erklärung helfen. Im obigen Code verbringt jede Task 25% Zeit mit Berechnungen und 75% mit I/O. Angenommen, eine Quad-Core-Maschine (kein Hyper-Threading), was sollte die Größe von Thread Pool N sein, um eine optimale Leistung zu erzielen, ohne Threads zu verschwenden, die unendliche I/O-Kapazität annehmen.Thread Pool Executor in Java

Antwort

1

Wenn Ihre Maschine über unbegrenzte E/A verfügt, bedeutet dies, dass Sie sich voll und ganz auf CPUs konzentrieren können. Jede Task verwendet während des Betriebs ein Viertel der CPU. Das bedeutet, Sie können vier Tasks ausführen, um einen CPU-Kern zu sättigen, und das macht N = 16 auf einem Quad-Core-Rechner.

Dies ist jedoch eine rein theoretische Antwort. In Wirklichkeit werden Sie mehrere Probleme finden, warum N = 16 zu groß oder zu klein sein könnte. Nehmen Sie zum Beispiel an, dass alle 16 Aufgaben in ihrer Planung identisch sind (CPU vs IO) und genau im selben Moment gestartet werden. Das würde bedeuten, dass in der ersten CPU-Zeit die Ausführungsgeschwindigkeit auf ein Viertel reduziert wird (16 Threads kämpfen für vier CPUs). Außerdem würde man annehmen, dass eine gewisse Menge an CPU-Last zum Ausführen des Betriebssystems, des Schedulers, der Müllsammlung und dergleichen erforderlich ist. Dies würde N = 16 zu groß machen.

Wenn es andererseits nicht erforderlich ist, dass jede Aufgabe mit der maximalen individuellen Geschwindigkeit ausgeführt wird, kann ein größeres N Ihnen eine bessere Gesamtleistung geben, wenn z. B. zu einem bestimmten Zeitrahmen mehr als 3/4 Da die Threads I/O ausführen, würden CPU-Ressourcen in diesem Moment ungenutzt bleiben.

Ich gehe davon aus, dass dies nicht der Punkt der Interviewfrage ist, aber in der realen Welt etwas zu beachten ist.

1

Wenn IO keine Einschränkung ist (aufgrund der unendlichen IO-Kapazität), können Sie sich auf die Anzahl der verfügbaren Kerne konzentrieren.

ExecutorService threadPool = Executors.newFixedThreadPool(
          Runtime.getRuntime().availableProcessors()); 

Die Leistung wird weiter verbessert, wenn Sie newWorkStealingPool in Testamentsvollstrecker (Release von 8 Java) verwenden

public static ExecutorService newWorkStealingPool() 

Erstellt eine Arbeit stiehlt Thread-Pool alle verfügbaren Prozessoren als Ziel Parallelität Ebene mit .