public class Demo5_ThreadPool extends ThreadPoolExecutor {
private final AtomicInteger submittedCount = new AtomicInteger(0);
public Demo5_ThreadPool(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, WorkedQueue workQueue) {
super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
workQueue.setParent(this);
prestartAllCoreThreads();
}
@Override
protected void afterExecute(Runnable r, Throwable t) {
submittedCount.decrementAndGet();
}
public int getSubmittedCount() {
return submittedCount.get();
}
@Override
public void execute(Runnable command) {
execute(command,0,TimeUnit.MILLISECONDS);
}
private void execute(Runnable command, long timeout, TimeUnit unit) {
submittedCount.incrementAndGet();
try {
super.execute(command);
} catch (RejectedExecutionException rx) {
final WorkedQueue queue = (WorkedQueue) super.getQueue();
try {
if (!queue.force(command, timeout, unit)) {
submittedCount.decrementAndGet();
throw new RejectedExecutionException("queue capacity is full");
}
} catch (InterruptedException e) {
submittedCount.decrementAndGet();
throw new RejectedExecutionException(e);
}
}
}
protected static class WorkedQueue extends LinkedBlockingQueue<Runnable> {
private static final long serialVersionUID = -7450459462714373019L;
private transient volatile Demo5_ThreadPool parent = null;
public WorkedQueue(int capacity) {
super(capacity);
}
public void setParent(Demo5_ThreadPool threadPool) {
this.parent = threadPool;
}
public boolean force(Runnable o) throws InterruptedException {
if (parent.isShutdown()) {
throw new RejectedExecutionException("Execute not running,can not force a command into the queue");
}
return super.offer(o);
}
public boolean force(Runnable o, long timeout, TimeUnit unit) throws InterruptedException {
if (parent.isShutdown()) {
throw new RejectedExecutionException("Execute not running,can not force a command into the queue");
}
return super.offer(o, timeout, unit);
}
@Override
public boolean offer(Runnable runnable) {
int currentPoolSize = parent.getPoolSize();
if (currentPoolSize >= parent.getMaximumPoolSize())
return super.offer(runnable);
if (currentPoolSize > parent.getSubmittedCount())
return super.offer(runnable);
if (currentPoolSize < parent.getMaximumPoolSize())
return false;
return super.offer(runnable);
}
}
}
可能会存在这种需求。。正常的情况是,创建线程池的时候规定了 corePoolSize,maximumPoolSize ,有界队列 10,任务执行,线程数量没达到 corePoolSize 会创建线程,直到达到corePoolSize,之后会放入线程队列中等待,直到队列满,则创建线程达到maximumPoolSize。这里,我们可以让它一直创建线程达到maximumPoolSize值。这样做自然有弊有利了。提供一个思路。