简体   繁体   English

ExecutorService 中的活动线程

[英]Active threads in ExecutorService

任何想法如何确定当前在ExecutorService运行的活动线程数?

Use a ThreadPoolExecutor implementation and call getActiveCount() on it:使用ThreadPoolExecutor实现并在其上调用getActiveCount()

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

The ExecutorService interface does not provide a method for that, it depends on the implementation. ExecutorService 接口没有为此提供方法,它取决于实现。

Assuming pool is the name of the ExecutorService instance:假设pool是 ExecutorService 实例的名称:

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

Check the sourcecode for Executors.newFixedThreadPool() :检查Executors.newFixedThreadPool()的源代码:

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

ThreadPoolExecutor has a getActiveCount() method. ThreadPoolExecutor 有一个 getActiveCount() 方法。 So you might either cast the ExecutorService to ThreadPoolExecutor, or use the above code directly to obtain one.因此,您可以将 ExecutorService 强制转换为 ThreadPoolExecutor,或者直接使用上面的代码来获取。 You can then invoke getActiveCount() .然后您可以调用getActiveCount()

The ExecutorService interface does not define a method to examine the number of worker threads in the pool, as this is an implementation detail ExecutorService 接口没有定义检查池中工作线程数量的方法,因为这是一个实现细节

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

Is available on the ThreadPoolExecutor class在 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());
    }
}

But this requires you to explicitly create the ThreadPoolExecutor, rather than using the Executors factory which returns ExecutorService objects.但这需要您显式创建 ThreadPoolExecutor,而不是使用返回 ExecutorService 对象的 Executors 工厂。 You could always create your own factory that returned ThreadPoolExecutors, but you would still be left with the bad form of using the concrete type, not its interface.您始终可以创建自己的返回 ThreadPoolExecutors 的工厂,但仍然会留下使用具体类型而不是其接口的糟糕形式。

One possibility would be to provide your own ThreadFactory which creates threads in a known thread group, which you can then count一种可能性是提供您自己的 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());
    }
}

I had same issue so created a simple Runnable to trace a ExecutorService instance.我遇到了同样的问题,因此创建了一个简单的 Runnable 来跟踪 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 ######");
        }

    }
}

You can simply use this with your executor to get states of ThreadPool您可以简单地将它与您的执行程序一起使用来获取 ThreadPool 的状态

Ex前任

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

Place a static volatile counter on the thread which is updated whenever the thread is activated and deactivated.在线程上放置一个静态易失性计数器,该计数器在线程激活和停用时更新。 Also, see the API.另请参阅 API。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM