Active threads no ExecutorService
-
09-06-2019 - |
Pergunta
Alguma idéia de como determinar o número de threads em execução no momento de uma ExecutorService
?
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.