一、情景分析
线程池size过小,导致大量任务Pending,但是由于页面关闭,因此Pending的任务没有继续执行的必要了,当然,正在执行的任务我们无需删除。
【1】如果是私有线程池,这个相对好办,调用shutDownNow,那么Pending的线程池就可以了不用继续执行了
【2】如果是公共线程池,暴露了 ThreadPoolExecutor的remove方法,调用即可(注意检查workQueue的remove方法是否安全,不可盲目)
public boolean remove(Runnable task) {
boolean removed = workQueue.remove(task);
tryTerminate(); // In case SHUTDOWN and now empty
return removed;
}
【3】如果是公共线程池,没有【2】,但暴露了队列WorkQueue,可以在队列中删除( 注意检查workQueue的remove方法是否安全,不可盲目 )
【4】如果workQueue和remove方法,甚至ThreadPoolExecutor都没有暴露,那么只能使用下列方式了
public class RemovableRunnable implements Runnable {
private Runnable target = null;
private Object lock = new Object();
public RemovableRunnable(Runnable task) {
this.target = task;
}
public static RemovableRunnable warp(Runnable r) {
return new RemovableRunnable(r);
}
@Override
public void run() {
Runnable task;
synchronized (this.lock) {
task = this.target;
}
if (task==null) {
return;
}
task.run();
}
public void dontRunIfPending() {
synchronized (this.lock) {
this.target = null
}
}
}
使用方式
private final List<RemovableRunnable> tasks = new ArrayList<>();
public void method(Runnable r)
{
RemovableRunnable task = RemovableRunnable.warp(r);
tasks.add(task);
PublicThreadPool.execute(task);
}
public void clearPendingTask() {
for (RemovableRunnable r : tasks){
r.dontRunIfPending();
}
}