在java项目中,为了以异步方式执行任务,我正在使用ThreadPoolExecutor。正如预期的那样,当我创建执行程序时,我正在设置核心和最大池大小以及有界(固定容量)队列。
如果我的任务被拒绝(所有线程都忙,队列已满),我会动态增加执行程序的max-pool-size,这样我就可以从队列中获取更多线程。
这是我目前使用的标准方法,但最近我遇到了不同的方法:
在此方法中,您可以设置核心和最大池大小以及无界队列,并按如下方式限制队列:
public class AsyncTaskexecutor {
private ThreadPoolExecutor threadPoolExecutor;
private int maxTasksInQueue;
private BlockingQueue queue;
public AsyncTaskexecutor(ThreadPoolExecutor threadPoolExecutor) {
this.queue = new LinkedBlockingQueue<>(); // creaing unbounded queue
this.threadPoolExecutor = createThreadPoolExecutor();
this.maxTasksInQueue = 100;
}
/**
* @return true if the task is either executed or pending in the queue for execution, else false (meaning rejected)
**/
public boolean executeAsync(Runnable task) {
if(this.queue.size() < maxTasksInQueue) {
threadPoolExecutor.execute(task);
return true;
} else {
return false; // rejected
}
}
private ThreadPoolExecutor createThreadPoolExecutor() {
ThreadFactory threadFactory = Executors.defaultThreadFactory();
ThreadPoolExecutor executor = new ThreadPoolExecutor(2, 4, 10, TimeUnit.SECONDS, this.queue, threadFactory, ThreadPoolExecutor.AbortPolicy);
return executor;
}
public void setQueueSize(int newSize) {
this.maxTasksInQueue = newSize;
}
}
因此,一旦任务被拒绝,就可以调用setQueueSize
方法并动态增加队列中的元素数量。
在第一种方法中,我们可以使用max-pool-size,这意味着我们绑定到cpu资源,而在第二种方法中,我们可以使用队列中的任务数量,这意味着我们绑定到内存资源。
两种方法都有效处理突发任务(尽可能避免拒绝)吗? 我在这里缺少任何其他优点/缺点?