我正在查看ThreadPoolExecutor
类,我发现它允许指定最大池大小和核心池大小。
我理解一点,关于何时根据答案更改核心和最大池大小:When is specifying separate core and maximum pool sizes in ThreadPoolExecutor a good idea?
但是,我想知道这些'核心线程'是什么。当我使用getCorePoolSize()
ThreadPoolExecutor
方法时,我总是得到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
}
}
答案 0 :(得分:5)
核心线程是始终运行的最小值,以防您想要将任务传递给它。默认情况下,缓存池的核心为0
,如您所料。
对于固定线程池,核心和最大值是相同的,即无论你设置固定大小的是什么。
答案 1 :(得分: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;
}
}
}
我刚才所说的内容基于allowCoreThreadTimeOut
设置为false
。
实际上,我更愿意将core threads
称为core workers
。