I have a method that will be called all the time.
After calling, a job(runnable) will be generated and submitted to the thread pool. The timeout time of each job is different, depending on the incoming parameters.
Now I want to monitor whether each job can end within the timeout time when it starts to execute. What should I do?
Note that timeout
is from the beginning of execution to the end of execution, not from the time of delivery to the thread pool to the end of task execution. Because of this, I don't think future #get (timeout)
can be used, am I right?.
And acceptJob
should not block, it has to return immediately after submitting the job(maybe some other logic, but not block).
ExecutorService pool = Executors.newFixedThreadPool(10);
public void acceptNewJob(Map<String, Object> params) {
// timeout from params
int timeoutInMs = (int) params.get("timeoutInMs");
pool.submit(new Runnable() {
@Override
public void run() {
// generate a job by params
// if this job execute timeout, need alarm
}
});
}
CodePudding user response:
How about wrapping every runnable and use a Timer
to check the runnable's status when the timeout period expires.
public void acceptNewJob(Map<String, Object> params) {
// timeout from params
int timeoutInMs = (int) params.get("timeoutInMs");
MonitoredRunnable runnable = new MonitoredRunnable(new Runnable() {
@Override
public void run() {
// generate a job by params
// if this job execute timeout, need alarm
}
}, timeoutInMs);
pool.submit(runnable);
}
// Or use ScheduledThreadPoolExecutor
private Timer timer = new Timer();
public class MonitoredRunnable implements Runnable {
private volatile int state = READY;
public static final int READY = 0;
public static final int RUNNING = 1;
public static final int COMPLETE = 0;
private Runnable task;
private int timeoutInMs;
public MonitoredRunnable(Runnable task, int timeoutInMs) {
this.task = task;
this.timeoutInMs = timeoutInMs;
}
@Override
public void run() {
state = RUNNING;
startMonitor(this);
task.run();
state = COMPLETE;
}
private void startMonitor(MonitoredRunnable runnable) {
timer.schedule(new TimerTask() {
@Override
public void run() {
try {
if (runnable.state != COMPLETE) {
System.out.println("Job timeout.");
// alarm
}
} catch (Exception e) {
//
}
}
}, runnable.timeoutInMs);
}