线程池执行器中的“核心线程”是什么?

3

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

根据这里的回答,我了解了一些有关何时根据情况更改核心和最大池大小的内容:When is specifying separate core and maximum pool sizes in ThreadPoolExecutor a good idea?

然而,我想知道这些'核心线程'是什么。当我使用ThreadPoolExecutorgetCorePoolSize()方法时,我总是得到0。

这里是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个回答

5

核心线程是始终运行的最小线程数,以防您需要传递任务。默认情况下,缓存池的核心线程数为0,这是您可能期望的。

对于固定线程池,核心和最大线程数相同,即您设置的固定大小。


好的,如果在“缓存线程池”中更改核心线程数,则类似于“固定线程池”,这些线程将始终存在。但是,未使用超过一分钟的线程将被丢弃。最终结果是结合了缓存和固定线程池的优点。对吗? - An SO User
你最终会创建一个池子,其中有少量的线程总是处于待命状态,其他线程则根据需要创建。空闲线程不会消耗内存,因为它们所占用的资源将被释放。 - An SO User

0

核心线程只是标准线程,但它们将始终保持在池中运行,而其他非核心线程将在其run()方法完成后结束生命。

但是这些核心线程如何始终保持活动状态呢?这是因为它们始终在等待从池内共享的workQueue中获取任务。默认情况下,workQueue是一个BlockingQueue,其take()方法将无限期地阻塞当前线程,直到任务变为可用。

这里是关键点,哪些线程将成为核心线程?它们可能不是第一个启动的线程或最后一个线程,而是持续时间最长的线程(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;
            }
        }
    }

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

实际上,我更喜欢把core threads称为core workers


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接