【问题标题】:Monitors whether the task submitted to the thread pool timed out监控提交到线程池的任务是否超时
【发布时间】:2021-12-28 00:46:48
【问题描述】:

我有一个会一直被调用的方法。

调用后会生成一个job(runnable)并提交给线程池。每个作业的超时时间不同,具体取决于传入的参数。

现在我想监控每个作业是否可以在它开始执行时的超时时间内结束。我该怎么办?

注意timeout是从执行开始到执行结束,而不是从交付到线程池的时间到任务执行结束。正因为如此,我觉得future #get (timeout)不能用了,对吧?

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

【问题讨论】:

    标签: java multithreading concurrency


    【解决方案1】:

    如何包装每个可运行对象并使用Timer 在超时期限到期时检查可运行对象的状态。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-03-15
      • 2016-06-24
      • 1970-01-01
      • 1970-01-01
      • 2012-12-28
      • 2014-11-25
      • 2018-04-16
      • 1970-01-01
      相关资源
      最近更新 更多