Java停止执行器服务,一旦其分配的任务之一因任何原因失败
我需要某种服务,可以同时运行几个任务,间隔1秒1分钟 如果其中一项任务失败,我希望停止服务,并停止运行的每项任务,同时显示出某种错误,否则,如果一分钟后一切正常,服务将停止,并显示一切正常 例如,我有两个函数:Java停止执行器服务,一旦其分配的任务之一因任何原因失败,java,multithreading,java-8,concurrency,runnable,Java,Multithreading,Java 8,Concurrency,Runnable,我需要某种服务,可以同时运行几个任务,间隔1秒1分钟 如果其中一项任务失败,我希望停止服务,并停止运行的每项任务,同时显示出某种错误,否则,如果一分钟后一切正常,服务将停止,并显示一切正常 例如,我有两个函数: Runnable task1 = ()->{ int num = Math.rand(1,100); if (num < 5){ throw new Exception("something went wrong with this
Runnable task1 = ()->{
int num = Math.rand(1,100);
if (num < 5){
throw new Exception("something went wrong with this task,terminate");
}
}
Runnable task2 = ()->{
int num = Math.rand(1,100)
return num < 50;
}
ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(2);
task1schedule = scheduledExecutorService.scheduleAtFixedRate(task1, 1, 60, TimeUnit.SECONDS);
task2schedule = scheduledExecutorService.scheduleAtFixedRate(task2, 1, 60, TimeUnit.SECONDS);
if (!task1schedule || !task2schedule) scheduledExecutorService.shutdown();
Runnable task1=()->{
int num=Math.rand(1100);
if(num<5){
抛出新异常(“此任务出现问题,终止”);
}
}
可运行任务2=()->{
int num=Math.rand(1100)
返回数<50;
}
ScheduledExecutorService ScheduledExecutorService=执行者。newScheduledThreadPool(2);
task1schedule=scheduledExecutorService.scheduleAtFixedRate(task1,1,60,TimeUnit.SECONDS);
task2schedule=scheduledExecutorService.scheduleAtFixedRate(task2,1,60,TimeUnit.SECONDS);
如果(!task1schedule | |!task2schedule)scheduledExecutorService.shutdown();
关于如何解决这个问题并使事情尽可能通用,您有什么想法吗?您只需要添加一个额外的任务,其任务是监视所有其他正在运行的任务——当任何被监视的任务失败时,他们需要设置刺客可以检查的信号量(标志)
ScheduledExecutorService executor = (ScheduledExecutorService) Executors.newScheduledThreadPool(2);
// INSTANTIATE THE REMOTE-FILE-MONITOR:
RemoteFileMonitor monitor = new RemoteFileMonitor(remotesource, localtarget);
// THIS TimerTask PERIODICALLY TRIGGERS THE RemoteFileMonitor:
TimerTask remote = new TimerTask() {
// RUN FORREST... RUN !
public void run() {
try {
kae.trace("TimerTask::run() --> Calling RemoteFileMonitor.check()");
monitor.check();
} catch (Exception ex) {
// NULL TRAP: ALLOWS US TO CONTINUE AND RETRY:
}
}
};
// THIS TimerTask PERIODICALLY TRIES TO KILL THE REMOTE-FILE-MONITOR:
TimerTask assassin = new TimerTask() {
// WHERE DO BAD FOLKS GO WHEN THEY DIE ?
private final LocalDateTime death = LocalDateTime.now().plus(ConfigurationOptions.getPollingCycleTime(), ChronoUnit.MINUTES);
// RUN FORREST... RUN !
public void run() {
// IS THERE LIFE AFTER DEATH ???
if (LocalDateTime.now().isAfter(death)) {
// THEY GO TO A LAKE OF FIRE AND FRY:
kae.error(ReturnCode.MONITOR_POLLING_CYCLE_EXCEEDED);
}
}
};
// SCHEDULE THE PERIODIC EXECUTION OF THE RemoteFileMonitor: (remote --> run() monitor --> check())
executor.scheduleAtFixedRate(remote, delay, interval, TimeUnit.MINUTES);
// SCHEDULE PERIODIC ASSASSINATION ATTEMPTS AGAINST THE RemoteFileMonitor: (assassin --> run() --> after death --> die())
executor.scheduleAtFixedRate(assassin, delay, 60L, TimeUnit.SECONDS);
// LOOP UNTIL THE MONITOR COMPLETES:
do {
try {
// I THINK I NEED A NAP:
Thread.sleep(interval * 10);
} catch (InterruptedException e) {
// FAIL && THEN cleanexit();
kae.error(ReturnCode.MONITORING_ERROR, "Monitoring of the XXXXXX-Ingestion site was interrupted");
}
// NOTE: THE MONITOR IS SET TO 'FINISHED' WHEN THE DONE-File IS DELIVERED AND RETRIEVED:
} while (monitor.isNotFinished());
// SHUTDOWN THE MONITOR TASK:
executor.shutdown();
其思想是任务正在推送到一个公共对象TaskCompleteEvent。如果他们推送错误,调度程序将停止,所有任务将停止 您可以在映射“错误”和“成功”中检查每个任务迭代的结果
公共类SchedulerTest{
@试验
public void scheduler()引发InterruptedException{
ScheduledExecutorService ScheduledExecutorService=执行者。newScheduledThreadPool(2);
TaskCompleteEvent TaskCompleteEvent=新的TaskCompleteEvent(scheduledExecutorService);
可运行任务1=()->{
int num=new Random().nextInt(100);
if(num<5){
消息(“task1-”+UUID.randomUUID().toString(),“Num”+Num+“已禁用。正在中断所有执行。”,true);
}
};
可运行任务2=()->{
int num=new Random().nextInt(100);
消息(“task2-”+UUID.randomUUID().toString(),num<50,false);
};
scheduledExecutorService.scheduleAtFixedRate(task1,0,1,TimeUnit.SECONDS);
scheduledExecutorService.scheduleAtFixedRate(task2、0、1,时间单位为秒);
scheduledExecutorService.等待终止(60,时间单位:秒);
System.out.println(“成功:+taskCompleteEvent.getSuccess());
System.out.println(“错误:+taskCompleteEvent.getErrors());
System.out.println(“进展顺利:”+taskCompleteEvent.getErrors().isEmpty());
}
公共静态类TaskCompleteEvent{
专用最终ScheduledExecutorService ScheduledExecutorService;
私有最终映射错误=新建LinkedHashMap();
私有最终映射成功=新建LinkedHashMap();
公共任务完成事件(ScheduledExecutorService ScheduledExecutorService){
this.scheduledExecutorService=scheduledExecutorService;
}
公共同步无效消息(字符串id、对象响应、布尔错误){
如果(错误){
错误。put(id,响应);
scheduledExecutorService.shutdown();
}否则{
success.put(id,response);
}
}
公共同步映射getErrors(){
返回错误;
}
公共同步映射getSuccess(){
回归成功;
}
}
}
除了实际问题之外,没有什么东西,Math.rand
不是内置的API。Runnable
的实现必须具有void run
定义。在提供的上下文中,task1/2schedule
的类型将是ScheduledFuture
。转到实际问题,它是如何利用的?您可以使用scheduledExecutorService.awaitTermination(1,TimeUnit.MINUTES)这样做代码>。或者,检查任务是否在正常完成之前被取消:if(task1schedule.isCancelled()| | task2schedule.isCancelled())scheduledExecutorService.shutdown()代码>?将任务安排在每分钟重复一次是没有意义的,但接着说,如果“一分钟后一切顺利”,您想停止任务。由于在这两种情况下都要停止执行器,因此安排一个在一分钟后关闭执行器的任务是微不足道的。而未来确实已经表明了是否出了问题。您没有说,您还需要什么类型的指示器。类TimerTask
与ScheduledExecutorService
完全无关;它恰好实现了Runnable
。此外,仅仅为了检查是否已达到特定时间(ConfigurationOptions.getPollingCycleTime()
),安排定期任务是没有意义的。您有一个ScheduledExecutorService
,因此您可以告诉它在所需的时间内正确安排任务。我使用的示例中的实现是,如果任务尚未完成,则在一段时间后终止正在执行的任务。使用案例是:如果远程服务器在2小时内没有删除文件,请终止该任务。这是OP要求的。你读过并理解我的评论了吗?不管代码做什么,它都会毫无理由地使用不推荐的类,只需将TimerTask
替换为Runnable
,就可以解决问题,而无需更改代码的功能。此外,只需使用executor.schedule(刺客,ConfigurationOptions.getPollingCycleTime(),ChronoUnit.MINUTES)代码>并且它将在所需时间运行一次,因此,
public class SchedulerTest {
@Test
public void scheduler() throws InterruptedException {
ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(2);
TaskCompleteEvent taskCompleteEvent = new TaskCompleteEvent(scheduledExecutorService);
Runnable task1 = () -> {
int num = new Random().nextInt(100);
if (num < 5) {
taskCompleteEvent.message("task1-"+UUID.randomUUID().toString(), "Num "+num+" was obatined. Breaking all the executions.", true);
}
};
Runnable task2 = () -> {
int num = new Random().nextInt(100);
taskCompleteEvent.message("task2-"+UUID.randomUUID().toString(), num < 50, false);
};
scheduledExecutorService.scheduleAtFixedRate(task1, 0, 1, TimeUnit.SECONDS);
scheduledExecutorService.scheduleAtFixedRate(task2, 0, 1, TimeUnit.SECONDS);
scheduledExecutorService.awaitTermination(60, TimeUnit.SECONDS);
System.out.println("Success: "+taskCompleteEvent.getSuccess());
System.out.println("Errors: "+taskCompleteEvent.getErrors());
System.out.println("Went well?: "+taskCompleteEvent.getErrors().isEmpty());
}
public static class TaskCompleteEvent {
private final ScheduledExecutorService scheduledExecutorService;
private final Map<String, Object> errors = new LinkedHashMap<>();
private final Map<String, Object> success = new LinkedHashMap<>();
public TaskCompleteEvent(ScheduledExecutorService scheduledExecutorService) {
this.scheduledExecutorService = scheduledExecutorService;
}
public synchronized void message(String id, Object response, boolean error) {
if (error) {
errors.put(id, response);
scheduledExecutorService.shutdown();
} else {
success.put(id, response);
}
}
public synchronized Map<String, Object> getErrors() {
return errors;
}
public synchronized Map<String, Object> getSuccess() {
return success;
}
}
}