一、情景分析
線程池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();
}
}