ThreadPoolExecutor中的核心线程是什么?

时间:2021-03-09 21:01:32

I was looking at the ThreadPoolExecutor class and I found that it allows to specify the maximum pool size and the core pool size.

我正在查看ThreadPoolExecutor类,我发现它允许指定最大池大小和核心池大小。

I understand, a little, about when to change the core and maximum pool sizes based on the answer here: When is specifying separate core and maximum pool sizes in ThreadPoolExecutor a good idea?

我有点了解何时根据这里的答案更改核心和最大池大小:何时在ThreadPoolExecutor中指定单独的核心和最大池大小是一个好主意?

However, I would like to know what are these 'core threads'. I always get 0 when I use the getCorePoolSize() method of a ThreadPoolExecutor

但是,我想知道这些“核心线程”是什么。当我使用ThreadPoolExecutor的getCorePoolSize()方法时,我总是得到0

SSCCE here:

SSCCE在这里:

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadPoolExecutor;

public class PoolSize {
    public static void main(String[] args) {
        // Create a cached thread pool
        ExecutorService cachedPool = Executors.newCachedThreadPool();
        // Cast the object to its class type
        ThreadPoolExecutor pool = (ThreadPoolExecutor) cachedPool;

        // Create a Callable object of anonymous class
        Callable<String> aCallable = new Callable<String>(){
            String result = "Callable done !";
            @Override
            public String call() throws Exception {
                // Print a value
                System.out.println("Callable at work !");
                // Sleep for 5 sec
                Thread.sleep(0);
                return result;
            }
        };

        // Create a Runnable object of anonymous class
        Runnable aRunnable = new Runnable(){
            @Override
            public void run() {
                try {
                    // Print a value
                    System.out.println("Runnable at work !");
                    // Sleep for 5 sec
                    Thread.sleep(0);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };

        // Submit the two tasks for execution
        Future<String> callableFuture = cachedPool.submit(aCallable);
        Future<?> runnableFuture = cachedPool.submit(aRunnable);

        System.out.println("Core threads: " + pool.getCorePoolSize());
        System.out.println("Largest number of simultaneous executions: " 
                                            + pool.getLargestPoolSize());
        System.out.println("Maximum number of  allowed threads: " 
                                            + pool.getMaximumPoolSize());
        System.out.println("Current threads in the pool: " 
                                            + pool.getPoolSize());
        System.out.println("Currently executing threads: " 
                                            + pool.getTaskCount());

        pool.shutdown(); // shut down

    }
}

2 个解决方案

#1


5  

core threads is the minimum which is always running just in case you want to pass it a task. The cached pool by default has a core of 0 as you might expect.

核心线程是最小的,它总是在你想要传递任务的情况下运行。默认情况下,缓存池的核心为0,如您所料。

For the fixed thread pool, the core and the maximum are the same i.e. whatever you set the fixed size to.

对于固定线程池,核心和最大值是相同的,即无论你设置固定大小。

#2


0  

The core threads are just standard threads but will be always kept alive in the pool, and then the other non-core threads will end their lives after the run() method finished.

核心线程只是标准线程,但在池中始终保持活动状态,然后其他非核心线程将在run()方法完成后终止生命。

But how could these core threads be always alive? That's because they are always waiting for taking a task from the workQueue shared within the pool. By default, the workQueue is a BlockingQueue, its take() method will block the current thread indefinitely until a task becomes available.

但是这些核心线程怎么能永远存在呢?那是因为他们总是在等待从池*享的workQueue中获取任务。默认情况下,workQueue是BlockingQueue,其take()方法将无限期地阻塞当前线程,直到任务可用。

Here comes the key point, which threads will become the core threads? They may not be the first started ones or the last ones, but the ones(corePoolSize) that last the longest. Easier to understand from the code.

这里有关键点,哪些线程将成为核心线程?它们可能不是第一个开始的或最后一个,而是持续时间最长的那些(corePoolSize)。从代码中更容易理解。

private Runnable getTask() {
        boolean timedOut = false; // Did the last poll() time out?

        for (;;) {
            int c = ctl.get();
            int rs = runStateOf(c);

            // Check if queue empty only if necessary.
            if (rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty())) {
                decrementWorkerCount();
                return null;
            }

            int wc = workerCountOf(c);

            //------------- key code ------------------
            // Are workers subject to culling?
            boolean timed = allowCoreThreadTimeOut || wc > corePoolSize;

            if ((wc > maximumPoolSize || (timed && timedOut))
                && (wc > 1 || workQueue.isEmpty())) {
                if (compareAndDecrementWorkerCount(c))
                    return null;
                continue;
            }

            //------------- key code ------------------
            try {
                Runnable r = timed ?
                    workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :
                    workQueue.take();
                if (r != null)
                    return r;
                timedOut = true;
            } catch (InterruptedException retry) {
                timedOut = false;
            }
        }
    }

What I just said above is based on allowCoreThreadTimeOut set as false.

我刚才所说的是基于allowCoreThreadTimeOut设置为false。

Actually, I prefer to call core threads as core workers.

实际上,我更喜欢将核心线程称为核心工作者。

#1


5  

core threads is the minimum which is always running just in case you want to pass it a task. The cached pool by default has a core of 0 as you might expect.

核心线程是最小的,它总是在你想要传递任务的情况下运行。默认情况下,缓存池的核心为0,如您所料。

For the fixed thread pool, the core and the maximum are the same i.e. whatever you set the fixed size to.

对于固定线程池,核心和最大值是相同的,即无论你设置固定大小。

#2


0  

The core threads are just standard threads but will be always kept alive in the pool, and then the other non-core threads will end their lives after the run() method finished.

核心线程只是标准线程,但在池中始终保持活动状态,然后其他非核心线程将在run()方法完成后终止生命。

But how could these core threads be always alive? That's because they are always waiting for taking a task from the workQueue shared within the pool. By default, the workQueue is a BlockingQueue, its take() method will block the current thread indefinitely until a task becomes available.

但是这些核心线程怎么能永远存在呢?那是因为他们总是在等待从池*享的workQueue中获取任务。默认情况下,workQueue是BlockingQueue,其take()方法将无限期地阻塞当前线程,直到任务可用。

Here comes the key point, which threads will become the core threads? They may not be the first started ones or the last ones, but the ones(corePoolSize) that last the longest. Easier to understand from the code.

这里有关键点,哪些线程将成为核心线程?它们可能不是第一个开始的或最后一个,而是持续时间最长的那些(corePoolSize)。从代码中更容易理解。

private Runnable getTask() {
        boolean timedOut = false; // Did the last poll() time out?

        for (;;) {
            int c = ctl.get();
            int rs = runStateOf(c);

            // Check if queue empty only if necessary.
            if (rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty())) {
                decrementWorkerCount();
                return null;
            }

            int wc = workerCountOf(c);

            //------------- key code ------------------
            // Are workers subject to culling?
            boolean timed = allowCoreThreadTimeOut || wc > corePoolSize;

            if ((wc > maximumPoolSize || (timed && timedOut))
                && (wc > 1 || workQueue.isEmpty())) {
                if (compareAndDecrementWorkerCount(c))
                    return null;
                continue;
            }

            //------------- key code ------------------
            try {
                Runnable r = timed ?
                    workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :
                    workQueue.take();
                if (r != null)
                    return r;
                timedOut = true;
            } catch (InterruptedException retry) {
                timedOut = false;
            }
        }
    }

What I just said above is based on allowCoreThreadTimeOut set as false.

我刚才所说的是基于allowCoreThreadTimeOut设置为false。

Actually, I prefer to call core threads as core workers.

实际上,我更喜欢将核心线程称为核心工作者。