it-swarm-pt.tech

Threads ativos no ExecutorService

Alguma idéia de como determinar o número de threads ativos atualmente em execução em um ExecutorService ?

58
zanussi

Use uma implementação ThreadPoolExecutor e chame getActiveCount () nela:

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

A interface ExecutorService não fornece um método para isso, depende da implementação.

63
Daan

Supondo que pool é o nome da instância ExecutorService:

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

Verifique o código-fonte para Executors.newFixedThreadPool ():

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

ThreadPoolExecutor possui um método getActiveCount (). Portanto, você pode converter o ExecutorService em ThreadPoolExecutor, ou use o código acima diretamente para obter um. Você pode invocar getActiveCount ().

21
Arno

A interface ExecutorService não define um método para examinar o número de threads de trabalho no pool, pois esse é um detalhe da implementação

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

Está disponível na classe ThreadPoolExecutor

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

Mas isso exige que você crie explicitamente o ThreadPoolExecutor, em vez de usar a fábrica Executors, que retorna objetos ExecutorService. Você sempre pode criar sua própria fábrica que retornou ThreadPoolExecutors, mas você ainda terá a má forma de usar o tipo concreto, não sua interface.

Uma possibilidade seria fornecer seu próprio ThreadFactory, que cria threads em um grupo de threads conhecido, que você pode contar

 importar Java.util.concurrent.ExecutorService; 
 importar Java.util.concurrent.Executors; 
 importar Java.util.concurrent.ThreadFactory; 
 
 
 classe pública PoolSize2 {
 
 public static void main (String [] args) {
 final ThreadGroup threadGroup = new ThreadGroup ("workers"); 
 
 ExecutorService executor = Executors.newCachedThreadPool (new ThreadFactory () {
 Público Thread newThread (Runnable r) {
 Retorna novo Thread (threadGroup, r); 
} 
}); 
 
 System.out.println (threadGroup.activeCount ()); 
} 
} 
10
Dave Cheney

Eu tive o mesmo problema, então criei um Runnable simples para rastrear uma instância de 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 ######");
        }

    }
}

Você pode simplesmente usar isso com seu executor para obter estados do ThreadPool

Ex

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