web-dev-qa-db-ja.com

ExecutorServiceのアクティブスレッド

ExecutorService ?で現在実行されているアクティブなスレッドの数を決定する方法はありますか?

58
zanussi

ThreadPoolExecutor 実装を使用し、その上で getActiveCount() を呼び出します。

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

ExecutorServiceインターフェースはそのためのメソッドを提供せず、実装に依存します。

63
Daan

poolがExecutorServiceインスタンスの名前であると仮定します:

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

Executors.newFixedThreadPool()のソースコードを確認します。

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

ThreadPoolExecutorにはgetActiveCount()メソッドがあります。したがって、ExecutorServiceをThreadPoolExecutorにキャストするか、上記のコードを直接使用して取得します。その後、getActiveCount()を呼び出すことができます。

21
Arno

ExecutorServiceインターフェースは、プール内のワーカースレッドの数を調べるメソッドを定義しません。これは実装の詳細です。

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

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、新しいLinkedBlockingQueue()); 
 System.out.println(executor.getPoolSize()); 
} 
} 

ただし、これには、ExecutorServiceオブジェクトを返すExecutorsファクトリを使用するのではなく、ThreadPoolExecutorを明示的に作成する必要があります。 ThreadPoolExecutorsを返す独自のファクトリをいつでも作成できますが、そのインターフェイスではなく、具象型を使用するという悪い形が残っています。

1つの可能性は、既知のスレッドグループにスレッドを作成する独自のThreadFactoryを提供することです。

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

同じ問題が発生したため、ExecutorServiceインスタンスをトレースする単純なRunnableを作成しました。

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

    }
}

Executorでこれを使用して、ThreadPoolの状態を取得できます。

Ex

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