Java定時器_ScheduledThreadPoolExecutor

Java定時器_ScheduledThreadPoolExecutorjava

延遲任務:在xx秒後執行該任務算法

週期任務:每xx秒執行一次任務ide

Timer存在一些缺陷,應該考慮使用ScheduleThreadPoolExecutor 來代替他。函數

能夠經過ScheduleThreadPoolExecutor 的構造函數或Executors 的newScheduleThreadPool工廠方法來建立該類的對象。spa

Timer在執行全部定時任務時只會建立一個線程。若是某個任務執行時間過長,那麼將破壞其餘TimerTask的定時精確性。線程

Timer另外一個問題是若是TimeTask拋出了一個未檢查的異常,那麼Timer將表現出槽糕的行爲。Timer線程並不捕獲異常,所以當TimerTask拋出未檢查的異常時將終止定時線程。這種狀況下,Timer也不會恢復線程的執行,而是會錯誤地認爲整個Timer都消失了。所以,已經被調度但還沒有執行的TimerTask將不會再執行,新的任務也不會被調度。這就是線程泄漏。code

 

ScheduledThreadPoolExecutor繼承結構

 

延遲任務和週期任務的執行

以下代碼片斷對象

package com.usoft.schedule;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * @author: Lenovo(2015-08-13 23:54)
 */
public class ScheduledTest {

    public static void main(String args[]) throws ExecutionException, InterruptedException {
        ScheduledExecutorService schedule = Executors
                .newScheduledThreadPool(2);

        /**
         * 延遲1秒執行任務一次
         */
        schedule.schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println("hello world runnable");
            }
        }, 1000, TimeUnit.MILLISECONDS);


        /**
         * 延遲2秒執行任務一次
         */
        Future result = schedule.schedule(new Callable<String>() {
            @Override
            public String call() throws Exception {
                return "hello world callable";
            }
        }, 2000, TimeUnit.MILLISECONDS);

        System.out.println(result.get());

        // 以固定的頻率來週期的執行任務
        schedule.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                System.out.println("定時週期任務執行");
            }
        }, 1000, 2000, TimeUnit.MILLISECONDS);


        // 以固定的延遲來週期的執行任務
        schedule.scheduleWithFixedDelay(new Runnable() {
            @Override
            public void run() {
                System.out.println("定時週期任務執行");
            }
        }, 1000, 3000, TimeUnit.MILLISECONDS);

        // 關閉定時和週期任務的執行
        Thread.sleep(1000 * 10);
        schedule.shutdown();//平緩的關閉
        System.out.println("pool shutdown:" + schedule.isShutdown());
        while (!schedule.isTerminated()) {
            schedule.awaitTermination(1, TimeUnit.SECONDS);
        }
    }
}

 

要說定時任務,其實都是用延遲任務和週期任務來實現定時的。繼承

好比說,我要在天天的中午12點啓動一個定時任務,就要根據當前程序的啓動時間來算出延遲多長時間來執行這個任務,而且是週期的執行,有一個固定的算法來算出延遲的時長。get

package com.usoft.schedule;

import java.util.Calendar;

public class Main23 {

    private static final int period = 1000 * 60; //秒
    private static final int one_day_millseconds = 24 * 60 * 60 * 1000;

    public static void main(String args[]) {
        int dayOfHour = 0; // 24h 制
        int minute = 0;
        int second = 0;
        long delay;  //首次執行任務的延遲
        Calendar c = Calendar.getInstance();
        long currentTime = c.getTimeInMillis();
        c.set(Calendar.HOUR_OF_DAY, dayOfHour);
        c.set(Calendar.MINUTE, minute);
        c.set(Calendar.SECOND, second);
        long executeTime = c.getTimeInMillis();
        delay = executeTime - currentTime < 0 ? (executeTime - currentTime + one_day_millseconds)
            : (executeTime - currentTime);
        System.out.println("DelayTimeInMillis =" + delay);
        System.out.println("DelayTimeInSecond =" + delay / 1000);
        System.out.println("DelayTimeInHour =" + delay / (1000 * 60 * 60));
    }
}

===============END===============

相關文章
相關標籤/搜索