ScheduledExecutorService異常分析

一、源碼解析

關(guān)注一塊代碼:

/**
     * 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產(chǎn)生的周期工作線程,如果遇到任何意外則會停止后續(xù)執(zhí)行;
如果執(zhí)行的Runnable線程任務(wù)沒有加異常,則會出現(xiàn)只執(zhí)行一次則線程停止的問題!特別引起重視!

三、總結(jié)

1、獲取一個線程池定時任務(wù)異常關(guān)閉的小tip,注意任何心跳類希望一直保持線程定時任務(wù),為保證線程可靠性,最好捕獲異常進(jìn)行相關(guān)保護(hù);
2、靈感源于代碼,因此切忌遇到問題要關(guān)注代碼底層實現(xiàn),學(xué)會看jdk文檔接口的詳細(xì)說明,可以少走很多彎路;
3、學(xué)習(xí)ScheduledFuture這個返回:

  • 繼承了Delayed, Future<V>兩個接口
  • long getDelay(TimeUnit unit);支持返回線程任務(wù)的最近間隔時間
  • future提供的cancel、get等方法用于任務(wù)取消或者獲取,作用也很重要,注意學(xué)習(xí)用法

四、測試代碼

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();
            }
            */
        }
    }
}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容