web-dev-qa-db-fra.com

Threads actifs dans ExecutorService

Des idées sur la façon de déterminer le nombre de threads actifs en cours d'exécution dans un ExecutorService ?

58
zanussi

Utilisez une implémentation ThreadPoolExecutor et appelez getActiveCount () dessus:

int getActiveCount() 
// Returns the approximate number of threads that are actively executing tasks.

L'interface ExecutorService ne fournit pas de méthode pour cela, cela dépend de l'implémentation.

63
Daan

En supposant que pool est le nom de l'instance ExecutorService:

if (pool instanceof ThreadPoolExecutor) {
    System.out.println(
        "Pool size is now " +
        ((ThreadPoolExecutor) pool).getActiveCount()
    );
}
24
andyroid

Vérifiez le code source pour Executors.newFixedThreadPool ():

return new ThreadPoolExecutor(nThreads, nThreads,
                              0L, TimeUnit.MILLISECONDS,
                              new LinkedBlockingQueue<Runnable>());

ThreadPoolExecutor a une méthode getActiveCount (). Donc, vous pouvez soit convertir ExecutorService en ThreadPoolExecutor, soit utiliser directement le code ci-dessus pour en obtenir un. Vous pouvez ensuite appeler getActiveCount ().

21
Arno

L'interface ExecutorService ne définit pas de méthode pour examiner le nombre de threads de travail dans le pool, car il s'agit d'un détail d'implémentation

public int getPoolSize()
Returns the current number of threads in the pool.

Est disponible sur la classe ThreadPoolExecutor

 import Java.util.concurrent.LinkedBlockingQueue; 
 import Java.util.concurrent.ThreadPoolExecutor; 
 import Java.util.concurrent.TimeUnit; 
 
 
 public class PoolSize {
 
 public static void main (String [] args) {
 ThreadPoolExecutor executor = new ThreadPoolExecutor (10, 20, 60L, TimeUnit .SECONDS, nouveau LinkedBlockingQueue ()); 
 System.out.println (executor.getPoolSize ()); 
} 
} 

Mais cela vous oblige à créer explicitement le ThreadPoolExecutor, plutôt que d'utiliser la fabrique Executors qui renvoie les objets ExecutorService. Vous pouvez toujours créer votre propre usine qui a renvoyé ThreadPoolExecutors, mais vous vous retrouvez toujours avec la mauvaise forme d'utilisation du type concret, pas son interface.

Une possibilité serait de fournir votre propre ThreadFactory qui crée des threads dans un groupe de threads connu, que vous pouvez ensuite compter

 import Java.util.concurrent.ExecutorService; 
 import Java.util.concurrent.Executors; 
 import Java.util.concurrent.ThreadFactory; 
 
 
 public class PoolSize2 {
 
 public static void main (String [] args) {
 final ThreadGroup threadGroup = nouveau ThreadGroup ("travailleurs"); 
 
 ExecutorService executor = Executors.newCachedThreadPool (new ThreadFactory () {
 Public Thread newThread (Runnable r) {
 Return new Thread (threadGroup, r); 
} 
}); 
 
 System.out.println (threadGroup.activeCount ()); 
} 
} 
10
Dave Cheney

J'ai eu le même problème, j'ai donc créé un Runnable simple pour tracer une instance ExecutorService.

import Java.util.concurrent.ExecutorService;
import Java.util.concurrent.ThreadPoolExecutor;

public class ExecutorServiceAnalyzer implements Runnable
{
    private final ThreadPoolExecutor threadPoolExecutor;
    private final int timeDiff;

    public ExecutorServiceAnalyzer(ExecutorService executorService, int timeDiff)
    {
        this.timeDiff = timeDiff;
        if (executorService instanceof ThreadPoolExecutor)
        {
            threadPoolExecutor = (ThreadPoolExecutor) executorService;
        }
        else
        {
            threadPoolExecutor = null;
            System.out.println("This executor doesn't support ThreadPoolExecutor ");
        }

    }

    @Override
    public void run()
    {
        if (threadPoolExecutor != null)
        {
            do
            {
                System.out.println("#### Thread Report:: Active:" + threadPoolExecutor.getActiveCount() + " Pool: "
                        + threadPoolExecutor.getPoolSize() + " MaxPool: " + threadPoolExecutor.getMaximumPoolSize()
                        + " ####");
                try
                {
                    Thread.sleep(timeDiff);
                }
                catch (Exception e)
                {
                }
            } while (threadPoolExecutor.getActiveCount() > 1);
            System.out.println("##### Terminating as only 1 thread is active ######");
        }

    }
}

Vous pouvez simplement l'utiliser avec votre exécuteur pour obtenir les états de ThreadPool

Ex

ExecutorService executorService = Executors.newFixedThreadPool(4);
    executorService.execute(new ExecutorServiceAnalyzer(executorService, 1000));
4
Ankit Katiyar