Pergunta

Alguma idéia de como determinar o número de threads em execução no momento de uma ExecutorService?

Foi útil?

Solução

Usar um ThreadPoolExecutor implementação e chamada de getActiveCount() sobre ele:

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

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

Outras dicas

Supondo pool é o nome do ExecutorService exemplo:

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

Verifique o código fonte para os Executores.newFixedThreadPool():

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

ThreadPoolExecutor tem um getActiveCount() método.Assim, você pode lançar o ExecutorService para ThreadPoolExecutor, oder usar o código acima directamente para obter um.Em seguida, você pode chamar getActiveCount().

O ExecutorService interface não define um método para examinar o número de threads de trabalho na piscina, pois este é um detalhe de implementação

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

Está disponível no ThreadPoolExecutor classe

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, new LinkedBlockingQueue());
        System.out.println(executor.getPoolSize());
    }
}

Mas isso requer que você criar explicitamente a ThreadPoolExecutor, em vez de usar os Executores de fábrica que retorna ExecutorService objetos.Você sempre pode criar a sua própria fábrica que voltou ThreadPoolExecutors, mas você ainda pode ficar com o mau usando o tipo concreto, e não a sua interface.

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

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 = new ThreadGroup("workers");

        ExecutorService executor = Executors.newCachedThreadPool(new ThreadFactory() {
            public Thread newThread(Runnable r) {
                return new Thread(threadGroup, r);
            }
        });

        System.out.println(threadGroup.activeCount());
    }
}

Eu tive o mesmo problema, então criei um simples Executável para rastrear um ExecutorService instância.

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 com o seu executor para fazer com que os estados de ThreadPool

Ex

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

Coloque um estática voláteis contador no thread que é atualizada sempre que o thread está activado e desactivado.Além disso, consulte a API.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top