2015年6月29日 星期一

排程 (Timer和TimerTask)

Timer的schedule、scheduleAtFixedRate主要差別是
schedule(4個)設定完後,下次會開始
scheduleAtFixedRate(2個)設定完後,連同之前的都會做

※TimerTask是個抽象類別,而且還implements Runnable,所以是個執行緒,要寫run(),也就是排程要執行的工作


public class Xxx extends TimerTask{
    public static void main(String[] args) {
        // 第一個參數為"欲執行的工作",會呼叫對應的run() method
        // 第二個參數為第一次執行的時間(Date)或延遲的時間(long)
        // 第三個參數為每幾毫秒做一次(是個選項,沒加就是只執行一次)
        new Timer().schedule(new Xxx(), new Date(), 3000L);
    }
    
    @Override
    public void run() {
        System.out.println(new Date());
    }
}
※也就是每3秒印一行

※如果沒有第三個參數,就是只執行一次
第二個參數如果是Date,表示哪時開始;如果是long,表示延遲多少毫秒才開始
schedule(TimerTask task, Date time)
schedule(TimerTask task, long delay)
schedule(TimerTask task, Date firstTime, long period)
schedule(TimerTask task, long delay, long period)


※匿名寫法

public static void main(String[] args) {
    new Timer().schedule(new TimerTask() {
        @Override
        public void run() {
            System.out.println(new Date());
        }
    }, new Date(), 3000L);
}


※schedule和scheduleAtFixedRate的差別

public static void main(String[] args) {
    Calendar cal = new GregorianCalendar(2016, Calendar.MARCH, 9, 13, 0, 0);
    System.out.println(new Date());
    // new Timer().schedule(new LoadOnStartup(), cal.getTime(), 2000);
    new Timer().scheduleAtFixedRate(new LoadOnStartup(), cal.getTime(), 2000);
}

※我測的時候是3月9號,我定的時間往前幾個小時,會補之前沒做的,但時間當然是現在的時間做

※Timer和TimerTask都有Cancel()可以取消排程



※單數次2秒執行、偶數次3秒執行

也就是第一次2秒執行,第二次3秒執行,第三次2秒執行,第四次3秒執行…依此類推

public class Test {
    static int i = 0;
    
    public static void main(String[] args) {
        class MyTimerTask extends TimerTask {
            @Override
            public void run() {
                i = (++i) % 2;
                System.out.println("ooo");
                // 2秒或3秒
                new Timer().schedule(new MyTimerTask(), 2000 + 1000 * i);
            }
        }
    
        new Timer().schedule(new MyTimerTask(), 2000);
    
        new Thread(() -> {
            for (;;) {
                try {
                    TimeUnit.SECONDS.sleep(1);
                    System.out.println(new Date().getSeconds());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }
}

※由於內部類別和方法內部不能寫 static 變數,所以寫到最外面

※改成 % 3 可以 2、3、4 秒循環

沒有留言:

張貼留言