При использовании java.util.concurrent.ThreadPoolExecutor
я хотел попробовать еще раз выполнить отклоненную задачу. Действительно ли это возможно? Я слышал об интерфейсе RejectedExecutionHandler
. Существует много доступных (известных) экземпляров интерфейса (RejectedExecutionHandler), таких как ThreadPoolExecutor.AbortPolicy, ThreadPoolExecutor.CallerRunsPolicy, ThreadPoolExecutor.DiscardOldestPolicy, ThreadPoolExecutor.DiscardPolicy и т. Д., Но проблема в том, что они не позволяют повторить выполнение.Использовать пользовательский RejectedExecutionHandler
ответ
Да, возможно повторить выполнение отклоненной задачи. Лучший способ повторить выполнение - использовать альтернативный исполнитель. Вы можете объявить пользовательский класс RejectedExecutionHandler просто так, как это делается с другими интерфейсами. Вот некоторые примеры кода:
public class MyRejectedExecutionHandler implements RejectedExecutionHandler {
@Override
public void rejectedExecution(Runnable worker, ThreadPoolExecutor executor) {
// TODO Auto-generated method stub
System.out.println(worker.toString()+" is Rejected");
System.out.println("Retrying to Execute");
try{
//Re-executing with alternateExecutor
MainClass.alternateExecutor.execute(worker);
System.out.println(worker.toString()+" Execution Started");
}
catch(Exception e)
{
System.out.println("Failure to Re-exicute "+e.getMessage());
}
}
}
Вы можете найти более подробную информацию об этом по адресу: http://examples.javacodegeeks.com/core-java/util/concurrent/rejectedexecutionhandler/java-util-concurrent-rejectedexecutionhandler-example/
Ниже повтор с поддержкой RejectedExecutionHandler, что не требует дополнительного ThreadPoolExecutor. Это более практично: когда задача была отклонена, отклоненная задача будет помещена в рабочий цикл ThreadPoolExecutor в режиме блокировки, что заставит истец задачи ждать некоторое время, прежде чем ThreadPoolExecutor сможет обработать любые другие задачи.
new RejectedExecutionHandler() {
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
if (!executor.isShutdown()) {
try {
executor.getQueue().put(r);
} catch (InterruptedException e) {
;
}
}
}
}
Это возможное решение, но довольно редкое, что потребуется. Если один пул отклоняет выполнение, это потому, что вы не должны передавать ему задания. –
отказ может также возникать из-за других проблем, таких как, если границы локальной памяти превышены, или если исполнитель был остановлен ранее. –