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

Posted

技术标签:

【中文标题】监控提交到线程池的任务是不是超时【英文标题】: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
        
    );

【问题讨论】:

【参考方案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);
    

【讨论】:

以上是关于监控提交到线程池的任务是不是超时的主要内容,如果未能解决你的问题,请参考以下文章

线程池的实现原理

多线程设置线程超时思路

java 如何获得线程池中正在执行的线程数?

线程池原理线程池的原理及实现

Java线程池