ThreadPoolExecutor的LinkedBlockingQueue 大小设置为10000,会溢出吗?
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),那肯定不会内存溢出的。
更多推荐
所有评论(0)