天天看點

多線程并發程式設計(二):定時器的應用定時器的應用Timer

定時器的應用

Timer

主要是幾種應用場景的使用

示例應用場景1:設定一個定時器,10秒之後爆炸

package test01;

import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

public class TraditionalTimerTest {

    public static void main(String[] args) {

        new Timer().schedule(new TimerTask() {

            @Override
            public void run() {
                System.out.println("boom!");
            }

        }, );

        while(true){
            System.out.println(new Date().getSeconds());
            try {
                Thread.sleep();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }
}
           

輸出結果:

多線程并發程式設計(二):定時器的應用定時器的應用Timer

示例應用場景2:設定一個定時器,10秒之後爆炸,之後每隔3秒炸一次

其實就是一個API的問題

package test01;

import java.util.Timer;
import java.util.TimerTask;

public class TraditionalTimerTest {

    public static void main(String[] args) {
        new Timer().schedule(new TimerTask() {

            @Override
            public void run() {
                System.out.println("boom!");
            }
        }, ,);
    }
}
           

示例應用場景3:設定一個定時器,2秒之後爆炸,之後4秒炸一次,然後2秒後再炸一次,4秒炸一次,依次循環

實作方式一:一個定時任務,使用靜态變量的值來控制時間

package test01;

import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

public class TraditionalTimerTest {
    // 設定一個靜态變量用來區分是哪個定時器
    static int count = ;

    public static void main(String[] args) {
        class MyTimerTask extends TimerTask{

            @Override
            public void run() {
                count = (count + ) % ;
                System.out.println("boom!");
                new Timer().schedule(new MyTimerTask(), +*count);
            }

        }
        new Timer().schedule(new MyTimerTask(), );

        // 每隔一秒列印時間,友善觀察作用,可以去掉
        while(true){
            System.out.println(new Date().getSeconds());
            try {
                Thread.sleep();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }
}
           

列印結果:

多線程并發程式設計(二):定時器的應用定時器的應用Timer

通過上面的列印結果可以看到,啟動,2秒炸了一次,然後4秒炸了一次,然後再2秒,4秒。。循環

代碼分析:

new Timer().schedule(new MyTimerTask(), );
           
首先主線程main方法執行下來,首先執行上面的Timer定時器,2秒後執行内部類MyTimerTask裡面的run方法,判斷靜态變量count的值,執行另外一個定時器,設定時間為4秒,然後4秒後定時器繼續執行MyTimerTask裡面的run方法,根據靜态變量的值,設定時間為2秒後執行,如此循環。

實作方式二:使用兩個定時任務,交替調用執行

package test01;

import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

public class TraditionalTimerTest {

    // 定時任務1,在裡面調用任務2,設定4秒
    class MyTimerTask1 extends TimerTask{

        @Override
        public void run() {
            System.out.println("boom!");
            new Timer().schedule(new MyTimerTask2(), );
        }

    }

    // 定時任務2,在裡面調用任務1,設定2秒
    class MyTimerTask2 extends TimerTask{

        @Override
        public void run() {
            System.out.println("boom!");
            new Timer().schedule(new MyTimerTask1(),);
        }

    }

    public static void main(String[] args) {

        new Timer().schedule(new TraditionalTimerTest(). new MyTimerTask1(), );

        while(true){
            System.out.println(new Date().getSeconds());
            try {
                Thread.sleep();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }
}
           

輸出結果:

多線程并發程式設計(二):定時器的應用定時器的應用Timer

當然這裡的結果跟方式一是一樣的,實作方式隻是思考的方式不一樣而已。

示例應用場景4:設定一個定時器,在某一個時間點執行,之後每隔2秒執行

package test01;

import java.util.Calendar;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

public class TraditionalTimerTest {

    public static void main(String[] args) {
        // 2016.04.19 13:43:30
        Calendar cal = Calendar.getInstance();
        cal.set(, , , ,  ,);
        System.out.println(cal.getTime());

        new Timer().schedule(new TimerTask() {

            @Override
            public void run() {
                System.out.println("boom!");
            }
        }, cal.getTime(),);

        while(true){
            System.out.println(new Date().getSeconds());
            try {
                Thread.sleep();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }
}
           

這裡設定2016.04.19 13:43:30 執行,然後每隔2秒執行一次

輸出結果:

多線程并發程式設計(二):定時器的應用定時器的應用Timer

分析:其實還是一個API的問題

另外,類似這種需求其實可以用Quartz這個架構去用,比這個友善多了。

繼續閱讀