Java 如何将后台线程(T1)中引发的异常通知给调度程序线程(T2)
我有一个调度器,它以固定的时间间隔拾取作业,每个作业都需要很长的时间来处理。当一个作业正在处理时,我们发送heartbeat,每隔5分钟在后台线程上更新数据库中的最后一个更新时间列,直到作业完全完成 问题:如果在发送心跳信号时后台线程抛出运行时异常,如何通知正在运行作业方法中处理作业的调度程序线程立即中止当前作业并移动到作业列表中的下一个作业 职业经理人Java 如何将后台线程(T1)中引发的异常通知给调度程序线程(T2),java,multithreading,spring-boot,executorservice,Java,Multithreading,Spring Boot,Executorservice,我有一个调度器,它以固定的时间间隔拾取作业,每个作业都需要很长的时间来处理。当一个作业正在处理时,我们发送heartbeat,每隔5分钟在后台线程上更新数据库中的最后一个更新时间列,直到作业完全完成 问题:如果在发送心跳信号时后台线程抛出运行时异常,如何通知正在运行作业方法中处理作业的调度程序线程立即中止当前作业并移动到作业列表中的下一个作业 职业经理人 @Scheduled public void pipelineRunner() { List<Job&g
@Scheduled
public void pipelineRunner() {
List<Job> jobs = getJobs(); //fetches tasks from database
for(Job job: jobs){
try{
heartBeatSender.startHeartBeat(job); // updates last_update_time column for the current job in database on background thread
runJob(job); // contains logic of processing a job, how to abort current job it is processing if heartbeat sender throws a runtime exception or how to notify or make scheduler thread throw exception so that it can move to next job in the list?
}catch(Exception e){}
finally{
heartBeatSender.stopHeartBeat(); //stops updating last_update_time col.
}
}
}
您发布的代码有点不一致,因为
HeartbeatSender
似乎可以向多个作业发送心跳,但客户端代码总是只触发一个。但是,如果您有另一个类也使用此HeartbeatSender
,您将计划两个心跳可运行程序,那么它将如何决定取消哪一个stopHeartbeat()
?更不用说,我无法说出它首先是如何取消它的,因为除了startHeartbeat()
调用之外,它不跟踪计划任务
因此,您可能想做的是让HeartbeatSender
按作业跟踪其心跳,以便它可以单独取消它们
class HeartbeatSender {
private final Map<Job, ScheduledFuture<?>> heartbeats = new HashMap<>();
// you can create a new executor in start, but I don't see why
private final ScheduledExecutorService heartbeatExecutor = newSingleThreadScheduledExecutor();
public void startHeartbeat(Job job) {
Runnable heartBeat= ...;
ScheduledFuture<?> schedule = executor.scheduleAtFixedRate(heartBeat, 0L, heartBeatInterval, TimeUnit.MILLISECONDS);
heartbeats.put(job, schedule); // remember so you can cancel later
}
public void stopHeartbeat(Job job) {
ScheduledFuture<?> schedule = heartbeats.remove(job);
if (schedule != null) {
schedule.cancel(false);
}
}
}
您希望将异常发送到哪个线程?在代码中,您会说它将在什么时候正确处理它?如果后台线程在.save(job)方法上抛出运行时异常,我希望它被通知给正在执行runJob方法的调度程序线程,以便它中止当前作业并移动到下一个作业。更新了问题。谢谢我在代码中没有真正看到问题(除了调度发生在您声明的
Runnable
中,我编辑了问题以更正此问题)。你是在问如何取消你安排的心跳吗?因为在异常之后,您确实为下一个作业启动了新的心跳。最好发布一篇公开实际问题的文章。
class HeartbeatSender {
private final Map<Job, ScheduledFuture<?>> heartbeats = new HashMap<>();
// you can create a new executor in start, but I don't see why
private final ScheduledExecutorService heartbeatExecutor = newSingleThreadScheduledExecutor();
public void startHeartbeat(Job job) {
Runnable heartBeat= ...;
ScheduledFuture<?> schedule = executor.scheduleAtFixedRate(heartBeat, 0L, heartBeatInterval, TimeUnit.MILLISECONDS);
heartbeats.put(job, schedule); // remember so you can cancel later
}
public void stopHeartbeat(Job job) {
ScheduledFuture<?> schedule = heartbeats.remove(job);
if (schedule != null) {
schedule.cancel(false);
}
}
}
for(Job job: jobs){
try {
heartBeatSender.startHeartBeat(job);
runJob(job);
} catch(Exception e) {
} finally{
heartBeatSender.stopHeartBeat(job); // stops heartbeat for this job
}
}