美文网首页
ScheduledExecutorService异常分析

ScheduledExecutorService异常分析

作者: 田园小丁 | 来源:发表于2018-03-21 19:29 被阅读0次

    一、源码解析

    关注一块代码:

    /**
         * Creates and executes a periodic action that becomes enabled first
         * after the given initial delay, and subsequently with the given
         * period; that is executions will commence after
         * {@code initialDelay} then {@code initialDelay+period}, then
         * {@code initialDelay + 2 * period}, and so on.
         * If any execution of the task
         * encounters an exception, subsequent executions are suppressed.
         * Otherwise, the task will only terminate via cancellation or
         * termination of the executor.  If any execution of this task
         * takes longer than its period, then subsequent executions
         * may start late, but will not concurrently execute.
         *
         * @param command the task to execute
         * @param initialDelay the time to delay first execution
         * @param period the period between successive executions
         * @param unit the time unit of the initialDelay and period parameters
         * @return a ScheduledFuture representing pending completion of
         *         the task, and whose {@code get()} method will throw an
         *         exception upon cancellation
         * @throws RejectedExecutionException if the task cannot be
         *         scheduled for execution
         * @throws NullPointerException if command is null
         * @throws IllegalArgumentException if period less than or equal to zero
         */
        public ScheduledFuture<?> scheduleAtFixedRate(Runnable command,
                                                      long initialDelay,
                                                      long period,
                                                      TimeUnit unit);
    

    二、说明

    由scheduleAtFixedRate产生的周期工作线程,如果遇到任何意外则会停止后续执行;
    如果执行的Runnable线程任务没有加异常,则会出现只执行一次则线程停止的问题!特别引起重视!

    三、总结

    1、获取一个线程池定时任务异常关闭的小tip,注意任何心跳类希望一直保持线程定时任务,为保证线程可靠性,最好捕获异常进行相关保护;
    2、灵感源于代码,因此切忌遇到问题要关注代码底层实现,学会看jdk文档接口的详细说明,可以少走很多弯路;
    3、学习ScheduledFuture这个返回:

    • 继承了Delayed, Future<V>两个接口
    • long getDelay(TimeUnit unit);支持返回线程任务的最近间隔时间
    • future提供的cancel、get等方法用于任务取消或者获取,作用也很重要,注意学习用法

    四、测试代码

    package FutureScheuledTest;
    
    import java.util.concurrent.Executors;
    import java.util.concurrent.ScheduledExecutorService;
    import java.util.concurrent.ScheduledFuture;
    import java.util.concurrent.TimeUnit;
    
    /**
     * Created by fwding on 2018/3/21 0021.
     */
    public class FutureScheduledTest {
        private static ScheduledFuture global_sfd;
        public static void main(String[] args) throws Exception {
            ScheduledExecutorService ses = Executors.newScheduledThreadPool(10);
            ScheduledFuture sfa = ses.scheduleAtFixedRate(new TimerTask("a"), 200,
                    1000, TimeUnit.MILLISECONDS);
            ScheduledFuture sfb = ses.scheduleAtFixedRate(new TimerTask("b"), 400,
                    1000, TimeUnit.MILLISECONDS);
            ScheduledFuture sfc = ses.scheduleAtFixedRate(new TimerTask("c"), 600,
                    1000, TimeUnit.MILLISECONDS);
            global_sfd = ses.scheduleAtFixedRate(new TimerTask("d"), 800,
                    1000, TimeUnit.MILLISECONDS);
            Thread.sleep(5000);
            sfa.cancel(true);
            sfb.cancel(true);
            sfc.cancel(true);
            global_sfd.cancel(true);
    
            Thread.sleep(5000);
            ses.shutdown();
        }
    
        static class TimerTask implements Runnable{
            private String id;
            public TimerTask(String id){
                this.id = id;
            }
            @Override
            public void run(){
                System.out.println(id);
                //
                System.out.println("ID:" + id +"------------THREAD_D:TIME DELAY:" +
                        global_sfd.getDelay(TimeUnit.MILLISECONDS));
                if (!id.equals("d") && global_sfd.getDelay(TimeUnit.MILLISECONDS) < 400) {
                    global_sfd.cancel(true);
                    System.out.println("ID:" + id +"------------stop the THREAD_D!!!!!!");
                    Thread.currentThread().stop();
                }
    
                //异常测试
                /*
                try {
                    int[] s = new int[2];
                    s[0] = 1;
                    s[1] = 2;
                    s[2] = 3;
                } catch (Exception e) {
                    e.printStackTrace();
                }
                */
            }
        }
    }
    
    

    相关文章

      网友评论

          本文标题:ScheduledExecutorService异常分析

          本文链接:https://www.haomeiwen.com/subject/kxenfftx.html