1 . ThreadPoolExecutor的LinkedBlockingQueue 大小設置爲10000(如下申明),會溢出嗎?
private final ExecutorService es = new ThreadPoolExecutor(8, 10, 100, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(10000));
回答:不會。
2. 先說下BlockingQueue,如果BlockQueue是空的,從BlockingQueue取東西的操作將會被阻斷進入等待狀態,直到BlockingQueue進了東西纔會被喚醒.同樣,如果BlockingQueue是滿的,任何試圖往裏存東西的操作也會被阻斷進入等待狀態,直到BlockingQueue裏有空間纔會被喚醒繼續操作.
3. 下面分析下原因:
看看下面ThreadPoolTaskExecutor的源碼:
public class ThreadPoolTaskExecutor extends ExecutorConfigurationSupport
implements AsyncListenableTaskExecutor, SchedulingTaskExecutor {
private final Object poolSizeMonitor = new Object();
private int corePoolSize = 1;
private int maxPoolSize = Integer.MAX_VALUE;
private int keepAliveSeconds = 60;
private int queueCapacity = Integer.MAX_VALUE;
private boolean allowCoreThreadTimeOut = false;
private TaskDecorator taskDecorator;
private ThreadPoolExecutor threadPoolExecutor;
/**
* Note: This method exposes an {@link ExecutorService} to its base class
* but stores the actual {@link ThreadPoolExecutor} handle internally.
* Do not override this method for replacing the executor, rather just for
* decorating its {@code ExecutorService} handle or storing custom state.
*/
@Override
protected ExecutorService initializeExecutor(
ThreadFactory threadFactory, RejectedExecutionHandler rejectedExecutionHandler) {
BlockingQueue<Runnable> queue = createQueue(this.queueCapacity);
ThreadPoolExecutor executor;
if (this.taskDecorator != null) {
executor = new ThreadPoolExecutor(
this.corePoolSize, this.maxPoolSize, this.keepAliveSeconds, TimeUnit.SECONDS,
queue, threadFactory, rejectedExecutionHandler) {
@Override
public void execute(Runnable command) {
super.execute(taskDecorator.decorate(command));
}
};
}
else {
executor = new ThreadPoolExecutor(
this.corePoolSize, this.maxPoolSize, this.keepAliveSeconds, TimeUnit.SECONDS,
queue, threadFactory, rejectedExecutionHandler);
}
if (this.allowCoreThreadTimeOut) {
executor.allowCoreThreadTimeOut(true);
}
this.threadPoolExecutor = executor;
return executor;
}
/**
* Set the capacity for the ThreadPoolExecutor's BlockingQueue.
* Default is {@code Integer.MAX_VALUE}.
* <p>Any positive value will lead to a LinkedBlockingQueue instance;
* any other value will lead to a SynchronousQueue instance.
* @see java.util.concurrent.LinkedBlockingQueue
* @see java.util.concurrent.SynchronousQueue
*/
public void setQueueCapacity(int queueCapacity) {
this.queueCapacity = queueCapacity;
}
LinkedBlockingQueue Default is {@code Integer.MAX_VALUE}.
ThreadPoolTaskExecutor是Spring core包中的,而ThreadPoolExecutor是JDK中的JUC。ThreadPoolTaskExecutor是對ThreadPoolExecutor進行了封裝處理。
從上面的源碼可以看出,也就是說我們平常使用的由Spring封裝的異步線程類,他默認LinkedBlockingQueue爲 Integer.MAX_VALUE大(即設置了ThreadPoolExecutor的LinkedBlockingQueue爲Integer.MAX_VALUE),我們天天都在用的異步執行器,天天都在正常使用!!!
現在我們直接設置ThreadPoolExecutor的LinkedBlockingQueue的大小爲10000(遠遠小於Integer.MAX_VALUE),那肯定不會內存溢出的。