Domanda

Qualche idea su come determinare il numero di thread attivi attualmente in esecuzione in un file ExecutorService?

È stato utile?

Soluzione

Usare un ThreadPoolExecutor attuazione e chiamata getActiveCount() su di essa:

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

L'interfaccia ExecutorService non fornisce un metodo per questo, dipende dall'implementazione.

Altri suggerimenti

Supponendo pool è il nome dell'istanza ExecutorService:

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

Controlla il codice sorgente per Executors.newFixedThreadPool():

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

ThreadPoolExecutor ha un metodo getActiveCount().Quindi potresti eseguire il cast di ExecutorService su ThreadPoolExecutor oppure utilizzare direttamente il codice sopra per ottenerne uno.È quindi possibile richiamare getActiveCount().

L'interfaccia ExecutorService non definisce un metodo per esaminare il numero di thread di lavoro nel pool, poiché si tratta di un dettaglio di implementazione

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

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

Ma ciò richiede la creazione esplicita di ThreadPoolExecutor, anziché utilizzare la factory Executors che restituisce oggetti ExecutorService.Potresti sempre creare la tua factory che restituisse ThreadPoolExecutors, ma ti rimarrebbe comunque la cattiva forma di utilizzare il tipo concreto, non la sua interfaccia.

Una possibilità sarebbe quella di fornire la propria ThreadFactory che crea thread in un gruppo di thread noto, che è quindi possibile contare

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());
    }
}

Ho avuto lo stesso problema, quindi ho creato un semplice Runnable per tracciare un'istanza di 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 ######");
        }

    }
}

Puoi semplicemente usarlo con il tuo esecutore per ottenere gli stati di ThreadPool

Ex

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

Posiziona un contatore volatile statico sul thread che viene aggiornato ogni volta che il thread viene attivato e disattivato.Inoltre, consulta l'API.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top