문제

현재 실행 중인 활성 스레드 수를 확인하는 방법에 대한 아이디어가 있습니까? ExecutorService?

도움이 되었습니까?

해결책

사용 ThreadPoolExecutor 구현 및 호출 getActiveCount() 그 위에:

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

ExecutorService 인터페이스는 이에 대한 메소드를 제공하지 않으며 구현에 따라 다릅니다.

다른 팁

가정 pool ExecutorService 인스턴스의 이름은 다음과 같습니다.

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

Executors.newFixedThreadPool()의 소스코드를 확인하세요.

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

ThreadPoolExecutor에는 getActiveCount() 메서드가 있습니다.따라서 ExecutorService를 ThreadPoolExecutor로 캐스팅하거나 위 코드를 직접 사용하여 얻을 수 있습니다.그런 다음 getActiveCount()를 호출할 수 있습니다.

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

그러나 이를 위해서는 ExecutorService 객체를 반환하는 Executors 팩토리를 사용하는 대신 ThreadPoolExecutor를 명시적으로 생성해야 합니다.언제든지 ThreadPoolExecutor를 반환하는 자체 팩토리를 만들 수 있지만 인터페이스가 아닌 구체적인 유형을 사용하는 잘못된 형식이 여전히 남게 됩니다.

한 가지 가능성은 알려진 스레드 그룹에 스레드를 생성하는 자체 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());
    }
}

동일한 문제가 있어서 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 ######");
        }

    }
}

간단히 실행기와 함께 이를 사용하여 ThreadPool의 상태를 얻을 수 있습니다.

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

스레드가 활성화 및 비활성화될 때마다 업데이트되는 정적 휘발성 카운터를 스레드에 배치합니다.또한 API를 참조하세요.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top