简体   繁体   English

监控提交到线程池的任务是否超时

[英]Monitors whether the task submitted to the thread pool timed out

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.调用后会生成一个job(runnable)并提交到线程池。 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.注意timeout是从执行开始到执行结束,而不是从交付到线程池到任务执行结束的时间。 Because of this, I don't think future #get (timeout) can be used, am I right?.因此,我认为不能使用future #get (timeout) ,对吗?。

And acceptJob should not block, it has to return immediately after submitting the job(maybe some other logic, but not block).并且acceptJob不应该阻塞,它必须在提交作业后立即返回(可能是其他一些逻辑,但不能阻塞)。

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
        }
    });
}

How about wrapping every runnable and use a Timer to check the runnable's status when the timeout period expires.如何包装每个 runnable 并使用Timer在超时期限到期时检查 runnable 的状态。

    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);
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM