歡迎關注個人微信公衆號:程序員私房菜(id:eson_15)java
傳統線程技術中有個定時器,定時器的類是Timer,咱們使用定時器的目的就是給它安排任務,讓它在指定的時間完成任務。因此先來看一下Timer類中的方法(主要看經常使用的TimerTask()
方法):程序員
返回值 | 方法名 | 方法描述 |
---|---|---|
void | schedule(TimerTask task, long delay) |
安排在指定延遲後執行指定的任務。 |
void | schedule(TimerTask task, long delay, long period) |
安排指定的任務從指定的延遲後開始進行重複的固定延遲執行。 |
void | schedule(TimerTask task, Date time) |
安排在指定的時間執行指定的任務 |
void | schedule(TimerTask task, Date firstTime, long period) |
安排指定的任務在指定的時間開始進行重複的固定延遲執行。 |
前面兩個是在指定延遲後執行或者重複執行,後面兩個是在指定時間執行或者重複執行。咱們之前兩個爲例來研究一下定時器的使用。微信
先寫一個簡單的使用定時器的demo,而後慢慢引伸。ide
public class TraditionalTimer {
public static void main(String[] args) {
//簡單定時器的demo
new Timer().schedule(new TimerTask() {
@Override
public void run() {
//實際中會扔一個對象進來,咱們就能夠在這裏操做這個對象的全部方法了
System.out.println("--boom--");//爆炸
}
}, 2000,3000);
//打印秒鐘,一秒輸出一次,用來方便觀察的
while(true) {
System.out.println(new Date().getSeconds());
try {
Thread.sleep(1000);
} catch(Exception e) {
e.printStackTrace();
}
}
}
}
複製代碼
咱們用匿名內部類來定義了一個TimerTask對象,須要重寫run()方法,而後運行這個程序,能夠看出來第一次2秒鐘後打印「--boom--,後面每隔3秒打印一次。spa
咱們也能夠本身來實現上面這個重複執行,咱們用定時器的「連環套」!也就是定時器中再套定時器,一個定時器任務執行完了,在任務的最後再裝一個定時器。那麼咱們須要先定義一個本身的定時器任務,在本身的定時器任務中再裝一個定時器,把自定義的定時器任務扔進去。而後咱們開啓定時器的時候把本身定義的定時器任務扔進去便可。以下:線程
public class TraditionalTimer {
public static void main(String[] args) {
//自定義一個定時器任務
class MyTimerTask extends TimerTask {
@Override
public void run() {
System.out.println("--boom--");
//任務執行完再裝一個定時器,扔進自定義的定時器任務
new Timer().schedule(new MyTimerTask(), 3000);
}
}
new Timer().schedule(new MyTimerTask(), 2000);//外面開啓定時器
while(true) {//打印秒鐘,一秒輸出一次
System.out.println(new Date().getSeconds());
try {
Thread.sleep(1000);
} catch(Exception e) {
e.printStackTrace();
}
}
}
}
複製代碼
這樣的話,咱們經過定時器的「連環套」很輕鬆的實現了連環爆炸。可是如今問題來了,上面提供的方法中重複執行都是每隔固定的時間,若是我想要隔2秒執行一次,再隔4秒執行一次,再隔2秒執行一次,再隔4秒執行一次……這該如何實現呢?code
能夠這樣,咱們定義一個全局的私有成員變量來記錄爆炸次數,奇數的時候隔2秒炸,偶數的次數的話隔4秒炸,或者反過來也行,修改以下:cdn
public class TraditionalTimer {
private static int count = 0; //記錄爆炸的次數
public static void main(String[] args) {
class MyTimerTask extends TimerTask {
@Override
public void run() {
count = (count + 1) % 2; //結果只有0和1
System.out.println("--boom--");
new Timer().schedule(new MyTimerTask(), 2000+2000*count);//根據count結果設定新的定時時間
}
}
new Timer().schedule(new MyTimerTask(), 2000);
while(true) {//打印秒鐘,一秒輸出一次
System.out.println(new Date().getSeconds());
try {
Thread.sleep(1000);
} catch(Exception e) {
e.printStackTrace();
}
}
}
}
複製代碼
這樣的話,咱們就實現了自定義爆炸間隔了。上面這個是經過定義一個全局私有變量來實現,其實咱們也能夠這麼幹:不是要實現兩個不一樣時間間隔的連環炸麼?我能夠定義兩個定時器任務A和B,在A執行完開啓定時器,把B任務裝進去,B執行完開啓定時器把A裝進去,這樣也能夠。以下:對象
public class TraditionalTimer {
public static void main(String[] args) {
new Timer().schedule(new MyTimerTaskA(), 2000);//A和B隨便開一個
while(true) {//打印秒鐘,一秒輸出一次
System.out.println(new Date().getSeconds());
try {
Thread.sleep(1000);
} catch(Exception e) {
e.printStackTrace();
}
}
}
}
//自定義兩個定時器任務類,繼承TimerTask便可
class MyTimerTaskA extends TimerTask {
@Override
public void run() {
System.out.println("--boomA--");
new Timer().schedule(new MyTimerTaskB(), 4000);
}
}
class MyTimerTaskB extends TimerTask {
@Override
public void run() {
System.out.println("--boomB--");
new Timer().schedule(new MyTimerTaskA(), 2000);
}
}
複製代碼
這樣就能夠實現自定義時間間隔的連環炸了。傳統的定時器技術就總結這麼多吧~若是有問題,歡迎指正,咱們一同進步!繼承
也歡迎你們關注個人微信公衆號:程序員私房菜。我會持續輸出更多文章。