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
.
实际上,我更喜欢将核心线程称为核心工作者。