3

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

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

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

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

    }
}
4

2 回答 2

5

核心线程是始终运行的最小值,以防万一您想将任务传递给它。默认情况下,缓存池具有0您可能期望的核心。

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

于 2013-11-09T07:49:47.470 回答
0

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

但是这些怎么可能core threads永远活着呢?那是因为他们总是在等待从workQueue池中的共享中获取任务。默认情况下,它workQueue是一个BlockingQueue,它的take()方法将无限期地阻塞当前线程,直到任务变得可用。

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

我刚才说的都是基于allowCoreThreadTimeOutset as false

实际上,我更喜欢调用core threadsas core workers

于 2017-06-05T11:00:22.903 回答