it-swarm-eu.dev

Aktive Threads in ExecutorService

Irgendwelche Ideen, wie man die Anzahl der aktiven Threads ermittelt, die derzeit in einem ExecutorService ausgeführt werden?

58
zanussi

Verwenden Sie eine ThreadPoolExecutor Implementierung und rufen Sie getActiveCount () auf:

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

Die ExecutorService-Schnittstelle stellt hierfür keine Methode zur Verfügung, sie hängt von der Implementierung ab.

63
Daan

Angenommen, pool ist der Name der ExecutorService-Instanz:

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

Überprüfen Sie den Quellcode für Executors.newFixedThreadPool ():

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

ThreadPoolExecutor verfügt über eine getActiveCount () -Methode. Sie können also entweder den ExecutorService in ThreadPoolExecutor umwandeln oder den obigen Code direkt verwenden, um einen zu erhalten. Sie können dann getActiveCount () aufrufen.

21
Arno

Die ExecutorService-Schnittstelle definiert keine Methode zum Überprüfen der Anzahl der Arbeitsthreads im Pool, da dies ein Implementierungsdetail ist

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

Ist in der ThreadPoolExecutor-Klasse verfügbar

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

Dies erfordert jedoch, dass Sie den ThreadPoolExecutor explizit erstellen, anstatt die Executors-Factory zu verwenden, die ExecutorService-Objekte zurückgibt. Sie könnten jederzeit eine eigene Factory erstellen, die ThreadPoolExecutors zurückgibt, aber Sie würden immer noch die schlechte Form haben, den konkreten Typ zu verwenden, nicht die Schnittstelle.

Eine Möglichkeit wäre, eine eigene ThreadFactory bereitzustellen, die Threads in einer bekannten Thread-Gruppe erstellt, die Sie dann zählen können

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

Ich hatte das gleiche Problem, also erstellte ich ein einfaches Runnable, um eine ExecutorService-Instanz zu verfolgen.

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 ######");
        }

    }
}

Sie können dies einfach mit Ihrem Executor verwenden, um den Status von ThreadPool abzurufen

Ex

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