java是否保证corepool线程在ThreadPoolExecutor中始终保持活动状态?
我多次运行我的测试代码,但似乎无法保证。
我尝试使用allowCoreThreadTimeOut = true和allowCoreThreadTimeOut = false。但是,行为没有变化。
这是我的测试代码。请尝试使用noOfTaskToRun 1和4的两个不同值。
public static void main(String[] args) {
int noOfTaskToRun = 1;
ThreadPoolExecutor executor = new ThreadPoolExecutor(2, 4, 2000, TimeUnit.MILLISECONDS, new SynchronousQueue<Runnable>());
executor.allowCoreThreadTimeOut(false);
List<Thread> threads = new ArrayList<Thread>();
for(int i = 0; i<noOfTaskToRun ; i++)
threads.add(new Thread("thread" + i) {
public void run() {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
for (Thread thread : threads) {
executor.execute(thread);
}
System.out.println("Before executor.getActiveCount(): "+ executor.getActiveCount());
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("After executor.getActiveCount(): "+ executor.getActiveCount());
}
我将keepAliveTime修改为2000.即使现在线程都超时了。
答案 0 :(得分:1)
我实际上并非百分百确定,但我认为getActiveCount()
不是您的想法。
文档说:“返回正在执行任务的大致线程数。”所以,我的猜测是空闲线程不包含在该数字中,但仍然可以存活。
你可能想要的是getPoolSize()
:“返回池中当前的线程数。”
增加:如果你的任务睡眠时间为5秒,并且你给他们所有人暂停了5秒,那么在超时之后他们中有多少人会完成...
答案 1 :(得分:0)
根据我的理解,它不会。我也看到了代码(JDK 6),似乎如果线程数在执行者的生命周期中小于corepoolthreads而不是它保证但是一旦超过限制就不能保证核心线程保持活着。
我尝试使用allowCoreThreadTimeOut = false运行。即使这样,如果线程数穿过coreThreadPoolSize,线程也会死亡。但是,如果线程数仍然小于coreThreadPoolSize,那么它们仍然存活。
我认为原因在于ThreadPoolExecutor类的这两种方法。来自workerCanExit会在队列为空时检查coreThreadPoolSize或allowCoreThreadTimeOut的值,这就是线程超时的原因。
Runnable getTask() {
for (;;) {
try {
int state = runState;
if (state > SHUTDOWN)
return null;
Runnable r;
if (state == SHUTDOWN) // Help drain queue
r = workQueue.poll();
else if (poolSize > corePoolSize || allowCoreThreadTimeOut)
r = workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS);
else
r = workQueue.take();
if (r != null)
return r;
if (workerCanExit()) {
if (runState >= SHUTDOWN) // Wake up others
interruptIdleWorkers();
return null;
}
// Else retry
} catch (InterruptedException ie) {
// On interruption, re-check runState
}
}
}
private boolean workerCanExit() {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
boolean canExit;
try {
canExit = runState >= STOP ||
workQueue.isEmpty() ||
(allowCoreThreadTimeOut &&
poolSize > Math.max(1, corePoolSize));
} finally {
mainLock.unlock();
}
return canExit;
}
答案 2 :(得分:0)
不,不能保证。例如,one of the constructors的javadoc表示:
“
corePoolSize
- 池中保留的线程数,即使它们处于空闲状态,除非设置了allowCoreThreadTimeOut
”
明显的含义是,如果你调用allowCoreThreadTimeOut(true)
,那么即使核心池线程也可以超时。
答案 3 :(得分:0)
根据ThreadPoolExecutor docs核心线程将保留在池中,即使它们处于空闲状态,除非设置了allowCoreThreadTimeOut标志。
核心线程死亡时的另一个情况是在任务执行期间抛出异常。在这种情况下,该线程将被替换为新线程。