1. 程式人生 > >schedule 任務排程偶發不執行問題

schedule 任務排程偶發不執行問題

  1. 實驗一

我們先看下下面這段簡單的程式碼。如下:

public class ExecutoryServiceTest {

        private static ScheduledExecutorService executorService = Executors.newScheduledThreadPool(10);

        publicstaticvoidmain(String[] args){
            executorService.scheduleAtFixedRate(new Runnable() {
                @Override
                
publicvoidrun()
{                        int[] array  = new int[1];                        System.out.println("<hello world>");                        System.out.println(array[1]);                }},0,2, TimeUnit.SECONDS);            }        }

夠簡單了吧。意思我就不再闡述了。看完別急,我們先回答下面這個問題。

問題一:

請問:上面一共列印了多少個<hello world>

實驗二

  看到此處的童鞋,請在評論區給出你第一個實驗的答案。緊接著,我們繼續看第二個實驗。

public class ExecutoryServiceTest {

        private static ScheduledExecutorService executorService = Executors.newScheduledThreadPool(10);

        publicstaticvoidmain(String[] args){
            executorService.scheduleAtFixedRate(new Runnable() {
                @Override
                
publicvoidrun()
{                    try {                        int[] array = new int[1];                        System.out.println("<hello world>");                        System.out.println(array[1]);                    }catch(Exception ex){                        ex.printStackTrace();                    }                }},0,2, TimeUnit.SECONDS);            }        }

問題二:

請問: 實驗二中一共列印了多少個<hello world>。

請在評論區中給出你的答案。

分析

  經過上述兩個實驗後,我們會發現兩者的答案並不相同。這是為什麼呢?因為在:run()方法中,發生異常後,中斷了後續的執行。這是為什麼呢?

其實呀,早在:scheduleAtFixedRate()JDK原始碼中就有這麼一段描述:

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.

其意思就是告訴我們:如果任何執行任務遇到異常,其後續的操作會被壓制。

同樣的,在scheduleWithFixedDelay()方法中也有同樣的描述

  1. 在使用scheduleAtFixedRate()scheduleWithFixedDelay()時,run()方法均要在使用try{}catch處理。避免出現定時任務執行若干次後不執行的”怪現象”。

  2. 我們平時在寫系統時,無論是使用JDK自帶函式,還是對接外部服務。使用時,一定要了解其使用方法。對入參,結果等都充分理解。(不瞞你說,我就出現過很多次沒理解充分。導致Bug產生)。今天我們一起來做個簡單有趣的實驗。熟悉Java的童鞋,對ScheduledExecutorService 類應該不陌生。不記得的童鞋,先回憶下。