<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          全面了解Java Timer定時(shí)器類

          共 37230字,需瀏覽 75分鐘

           ·

          2021-04-01 02:38

          點(diǎn)擊上方藍(lán)色字體,選擇“標(biāo)星公眾號(hào)”

          優(yōu)質(zhì)文章,第一時(shí)間送達(dá)

          Timer類介紹

          Timer類的主要作用是設(shè)置計(jì)劃任務(wù),即在指定時(shí)間開(kāi)始執(zhí)行某一個(gè)任務(wù)。Timer主要方法如圖:


          schedule(TimerTask task, Date time)方法測(cè)試

          該方法的作用是在指定日期執(zhí)行一次某一任務(wù)。

          TimerTask類:

          import java.util.TimerTask;

          public class MyTask extends TimerTask {
              @Override
              public void run() {
                  System.out.println("任務(wù)開(kāi)始了,執(zhí)行時(shí)間為:"+System.currentTimeMillis());
              }
          }

          測(cè)試類

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

          public class testTimer {
              public static void main(String[] args) throws InterruptedException{
                  Long nowTime=System.currentTimeMillis();
                  System.out.println("當(dāng)期時(shí)間為"+nowTime);
                  long scheduleTime=nowTime+10000;
                  System.out.println("開(kāi)始執(zhí)行時(shí)間:"+scheduleTime);

                  MyTask myTask = new MyTask();
                  Timer timer = new Timer();
                  Thread.sleep(1000);

                  timer.schedule(myTask,new Date(scheduleTime));
                  Thread.sleep(Integer.MAX_VALUE);
              }
          }

          10秒之后任務(wù)執(zhí)行完了,但是進(jìn)程還沒(méi)有銷毀,還在呈紅色按鈕。說(shuō)明內(nèi)部還有線程在執(zhí)行。為什么會(huì)出現(xiàn)這種情況?

          查看Timer類的源碼可以知道是因?yàn)樵趧?chuàng)建Timer對(duì)象時(shí)啟動(dòng)了一個(gè)新的進(jìn)程。

          private final TimerThread thread = new TimerThread(queue);
          public Timer(String name) {
                  thread.setName(name);
                  thread.start();
              }

          TimerThread 是線程類,但是并不是一個(gè)守護(hù)線程,而且還一直在運(yùn)行,一直在運(yùn)行的原因是線程內(nèi)部有一個(gè)死循環(huán),mainLoop()方法,其源碼如下:

           private void mainLoop() {
                  while (true) {
                      try {
                          TimerTask task;
                          boolean taskFired;
                          synchronized(queue) {
                              // Wait for queue to become non-empty
                              while (queue.isEmpty() && newTasksMayBeScheduled)
                                  queue.wait();
                              if (queue.isEmpty())
                                  break; // Queue is empty and will forever remain; die

                              // Queue nonempty; look at first evt and do the right thing
                              long currentTime, executionTime;
                              task = queue.getMin();
                              synchronized(task.lock) {
                                  if (task.state == TimerTask.CANCELLED) {
                                      queue.removeMin();
                                      continue;  // No action required, poll queue again
                                  }
                                  currentTime = System.currentTimeMillis();
                                  executionTime = task.nextExecutionTime;
                                  if (taskFired = (executionTime<=currentTime)) {
                                      if (task.period == 0) { // Non-repeating, remove
                                          queue.removeMin();
                                          task.state = TimerTask.EXECUTED;
                                      } else { // Repeating task, reschedule
                                          queue.rescheduleMin(
                                            task.period<0 ? currentTime   - task.period
                                                          : executionTime + task.period);
                                      }
                                  }
                              }
                              if (!taskFired) // Task hasn't yet fired; wait
                                  queue.wait(executionTime - currentTime);
                          }
                          if (taskFired)  // Task fired; run it, holding no locks
                              task.run();
                      } catch(InterruptedException e) {
                      }
                  }

          private void mainLoop() 方法內(nèi)部使用while死循環(huán)一直執(zhí)行計(jì)劃任務(wù),并不退出循環(huán),但是根據(jù)源碼的執(zhí)行流程,退出循環(huán)的核心代碼如下:

           while (queue.isEmpty() && newTasksMayBeScheduled)
                                  queue.wait();
                              if (queue.isEmpty())
                                  break; // Queue is empty and will forever remain; die


          下面我們來(lái)簡(jiǎn)單分析一下源代碼


          1)使用while循環(huán)對(duì)queue.isEmpty()&&newTasksMayBeScheduled條件進(jìn)行判斷。

          2)當(dāng)&&兩端運(yùn)算結(jié)果都為true時(shí),執(zhí)行wait()方法使當(dāng)前線程暫停運(yùn)行,等待被喚醒。

          3)喚醒線程的時(shí)機(jī)是執(zhí)行了public void schedule(TimerTask task, Date time)方法。

          4)喚醒線程后while繼續(xù)判斷queue.isEmpty()&&newTasksMayBeScheduled條件。如果queue.isEmpty()結(jié)果為true,則說(shuō)明隊(duì)列里并沒(méi)有任務(wù)執(zhí)行,而且boolean newTasksMayBeScheduled的值由true變成false,繼續(xù)執(zhí)行下面的if語(yǔ)句。

          5)if (queue.isEmpty())中的結(jié)果為true,說(shuō)明隊(duì)列為空,那么就執(zhí)行break語(yǔ)句退出while()死循環(huán)。

          6)執(zhí)行public void cancel(),則會(huì)使boolean變量newTasksMayBeScheduled的值有true變成false。

          7)不執(zhí)行public void cancel()方法,則變量newTasksMayBeScheduled的值就不會(huì)是false,進(jìn)程就會(huì)一直呈死循環(huán)的狀態(tài),進(jìn)程不銷毀的原因就是因?yàn)檫@個(gè)。cancel()方法源代碼如下

           public void cancel() {
                  synchronized(queue) {
                      thread.newTasksMayBeScheduled = false;
                      queue.clear();
                      queue.notify();  // In case queue was already empty.
                  }
              }

          使用cancel方法來(lái)銷毀線程

          Timer類中的cancel方法作用就是終止此計(jì)時(shí)器,當(dāng)前安排的一切任務(wù)都不會(huì)執(zhí)行。不過(guò)這并不會(huì)干擾當(dāng)前正在執(zhí)行的任務(wù)(如果存在當(dāng)前任務(wù))。一旦終止了計(jì)時(shí)器,那么他執(zhí)行的線程也會(huì)終止,并且無(wú)法根據(jù)他安排更多的任務(wù)。

          根據(jù)上面的源代碼分析可知,當(dāng)隊(duì)列為空,并且newTasksMayBeScheduled的值是false時(shí)退出死循環(huán),導(dǎo)致TimerThread線程結(jié)束運(yùn)行并且銷毀。

          創(chuàng)建Test2類代碼如下:

          public class Test2 {
              public static void main(String[] args) throws InterruptedException{
                  Long nowTime=System.currentTimeMillis();
                  System.out.println("當(dāng)期時(shí)間為"+nowTime);
                  long scheduleTime=nowTime+15000;
                  System.out.println("開(kāi)始執(zhí)行時(shí)間:"+scheduleTime);

                  MyTask myTask = new MyTask();
                  Timer timer = new Timer();

                  timer.schedule(myTask,new Date(scheduleTime));
                  Thread.sleep(18000);
                  timer.cancel();
              }
          }


          可見(jiàn)全部線程已經(jīng)銷毀了。


          schedule(TimerTask task, Date time)方法的幾種情況測(cè)試

          計(jì)劃早于當(dāng)前時(shí)間—立即執(zhí)行當(dāng)前任務(wù)

          mytask類

          public class MyTask extends TimerTask {
              @Override
              public void run() {
                  System.out.println("任務(wù)執(zhí)行了,時(shí)間為:"+System.currentTimeMillis());
              }
          }


          //計(jì)劃早于當(dāng)前時(shí)間---立即執(zhí)行當(dāng)前任務(wù)
          public class Test1 {
              public static void main(String[] args) {
                  long nowTime=System.currentTimeMillis();
                  System.out.println("當(dāng)前時(shí)間:"+nowTime);

                  long scheduleTime=(nowTime-5000);
                  System.out.println("計(jì)劃時(shí)間為:"+scheduleTime);

                  MyTask myTask = new MyTask();

                  Timer timer = new Timer();
                  timer.schedule(myTask,new Date(scheduleTime));
              }
          }
          結(jié)果:
          當(dāng)前時(shí)間:1616912643987
          計(jì)劃時(shí)間為:1616912638987
          任務(wù)執(zhí)行了,時(shí)間為:1616912643987

          schedule方法可以執(zhí)行多個(gè)任務(wù)

          //執(zhí)行多個(gè)任務(wù)
          public class Test2 {
              public static void main(String[] args){
                  long nowTime=System.currentTimeMillis();
                  System.out.println("當(dāng)前時(shí)間:"+nowTime);

                  long scheduleTime=(nowTime+5000);
                  long scheduleTime2=(nowTime+8000);
                  System.out.println("計(jì)劃時(shí)間為:"+scheduleTime);
                  System.out.println("計(jì)劃時(shí)間為:"+scheduleTime2);

                  MyTask myTask = new MyTask();
                  MyTask myTask2 = new MyTask();

                  Timer timer = new Timer();
                  timer.schedule(myTask,new Date(scheduleTime));
                  timer.schedule(myTask2,new Date(scheduleTime2));
              }
          }
          結(jié)果:
          當(dāng)前時(shí)間:1616912808406
          計(jì)劃時(shí)間為:1616912813406
          計(jì)劃時(shí)間為:1616912816406
          任務(wù)執(zhí)行了,時(shí)間為:1616912813417
          任務(wù)執(zhí)行了,時(shí)間為:1616912816407

          延時(shí)執(zhí)行TimerTask

          TimerTask以隊(duì)列的方式逐一按順序執(zhí)行,所以執(zhí)行的時(shí)間可能與預(yù)期時(shí)間并不一致,因?yàn)榍懊嫒蝿?wù)可能消耗的時(shí)間較長(zhǎng),后面的任務(wù)運(yùn)行時(shí)間可能被延后。

          public class MyTaskA extends TimerTask {
              @Override
              public void run() {
                  try {
                      System.out.println("A begin time=" + System.currentTimeMillis());
                      Thread.sleep(10000);
                      System.out.println("A end time=" + System.currentTimeMillis());
                  }catch (Exception e){
                      e.printStackTrace();
                  }
              }
          }

          public class MyTaskB extends TimerTask {
              @Override
              public void run() {
                  try {
                      System.out.println("B begin time=" + System.currentTimeMillis());
                      Thread.sleep(10000);
                      System.out.println("B end time=" + System.currentTimeMillis());
                  }catch (Exception e){
                      e.printStackTrace();
                  }
              }
          }


          測(cè)試類:

          public class Test3 {
              public static void main(String[] args) {
                  long nowTime=System.currentTimeMillis();
                  System.out.println("當(dāng)前時(shí)間:"+nowTime);

                  long scheduleTime=nowTime;
                  long scheduleTime2=(nowTime+5000);
                  System.out.println("計(jì)劃時(shí)間為:"+scheduleTime);
                  System.out.println("計(jì)劃時(shí)間為:"+scheduleTime2);
                  MyTaskA myTaskA = new MyTaskA();
                  MyTaskB myTaskB = new MyTaskB();

                  Timer timer = new Timer();
                  timer.schedule(myTaskA,new Date(scheduleTime));
                  timer.schedule(myTaskB,new Date(scheduleTime2));
              }
          }
          結(jié)果:
          當(dāng)前時(shí)間:1616913423195
          計(jì)劃時(shí)間為:1616913423195
          計(jì)劃時(shí)間為:1616913428195
          A begin time=1616913423195
          A end time=1616913433196
          B begin time=1616913433196
          B end time=1616913443211

          計(jì)劃B原本執(zhí)行的時(shí)間是long scheduleTime2=(nowTime+5000);與計(jì)劃A運(yùn)行間隔時(shí)間為5秒,但是因?yàn)锳任務(wù)運(yùn)行需要10秒,所有任務(wù)A執(zhí)行結(jié)束的時(shí)間就是任務(wù)B開(kāi)始的時(shí)間。


          schedule(TimerTask task, Date firstTime, long period)方法測(cè)試

          計(jì)劃時(shí)間晚于當(dāng)前時(shí)間————在未來(lái)執(zhí)行的效果

          該方法的作用是在指定日期之后按照指定的時(shí)間間隔無(wú)限的執(zhí)行某一個(gè)任務(wù)。

          public class Test3 {
              public static void main(String[] args) {
                  long nowTime=System.currentTimeMillis();
                  System.out.println("當(dāng)前時(shí)間:"+nowTime);

                  long scheduleTime=(nowTime+10000);
                  System.out.println("計(jì)劃時(shí)間為:"+scheduleTime);

                  MyTask myTask = new MyTask();

                  Timer timer = new Timer();
                  timer.schedule(myTask,new Date(scheduleTime),4000);
              }
          }
          結(jié)果:
          計(jì)劃時(shí)間為:1616914137464
          任務(wù)執(zhí)行了,時(shí)間為:1616914137474
          任務(wù)執(zhí)行了,時(shí)間為:1616914141494
          任務(wù)執(zhí)行了,時(shí)間為:1616914145514
          任務(wù)執(zhí)行了,時(shí)間為:1616914149534

          從程序的運(yùn)行結(jié)果來(lái)看每隔4秒運(yùn)行一次,并且無(wú)限重復(fù)的執(zhí)行該任務(wù)。

          計(jì)劃時(shí)間早于當(dāng)前時(shí)間————立即執(zhí)行的效果

          public class Test3 {
              public static void main(String[] args) {
                  long nowTime=System.currentTimeMillis();
                  System.out.println("當(dāng)前時(shí)間:"+nowTime);

                  long scheduleTime=(nowTime-10000);
                  System.out.println("計(jì)劃時(shí)間為:"+scheduleTime);

                  MyTask myTask = new MyTask();

                  Timer timer = new Timer();
                  timer.schedule(myTask,new Date(scheduleTime),4000);
              }
          }
          結(jié)果:
          當(dāng)前時(shí)間:1616914545243
          計(jì)劃時(shí)間為:1616914535243
          任務(wù)執(zhí)行了,時(shí)間為:1616914545243
          任務(wù)執(zhí)行了,時(shí)間為:1616914549253
          任務(wù)執(zhí)行了,時(shí)間為:1616914553254
          任務(wù)執(zhí)行了,時(shí)間為:1616914557264
          任務(wù)執(zhí)行了,時(shí)間為:1616914561283


          延時(shí)執(zhí)行TimerTask任務(wù)

          public class Test3 {
              public static void main(String[] args) {
                  long nowTime=System.currentTimeMillis();
                  System.out.println("當(dāng)前時(shí)間:"+nowTime);

                  long scheduleTime=nowTime;
                  System.out.println("計(jì)劃時(shí)間為:"+scheduleTime);
                  MyTaskA myTaskA = new MyTaskA();

                  Timer timer = new Timer();
                  timer.schedule(myTaskA,new Date(scheduleTime),4000);
              }
          }
          結(jié)果:
          當(dāng)前時(shí)間:1616914846353
          計(jì)劃時(shí)間為:1616914846353
          A begin time=1616914846353
          A end time=1616914851363
          A begin time=1616914851363
          A end time=1616914856373
          A begin time=1616914856373
          A end time=1616914861383

          代碼schedule(myTaskA,new Date(scheduleTime),4000);本來(lái)計(jì)劃每個(gè)任務(wù)執(zhí)行時(shí)間為4秒但是任務(wù)A執(zhí)行了Thread.sleep(5000)要5秒。


          TimerTask類中的cancel()方法和Timer中的cancel()方法的區(qū)別

          TimerTask類中的cancel()方法

          TimerTask類中的cancel()方法作用是將自己在任務(wù)隊(duì)列中清除。該方法的源代碼如下

           public boolean cancel() {
                  synchronized(lock) {
                      boolean result = (state == SCHEDULED);
                      state = CANCELLED;
                      return result;
                  }
              }

          從方法的源代碼可以分析出執(zhí)行TimerTask中的該方法,當(dāng)前任務(wù)TimerTask任務(wù)的state狀態(tài)將會(huì)變成CANCELLED。

          public class MyThreadA extends TimerTask {
              @Override
              public void run() {
                  System.out.println("A run time="+System.currentTimeMillis());
                  this.cancel();
                  System.out.println("A任務(wù)將自己移除");
              }
          }
          class MyThreadB extends TimerTask{
              @Override
              public void run() {
                  System.out.println("B run time="+System.currentTimeMillis());
              }
          }
          class test{
              public static void main(String[] args) {
                  long nowTime=System.currentTimeMillis();
                  System.out.println("當(dāng)前時(shí)間:"+nowTime);
                  System.out.println("計(jì)劃時(shí)間為:"+nowTime);
                  MyThreadB myThreadB = new MyThreadB();
                  MyThreadA myThreadA = new MyThreadA();
                  Timer timer = new Timer();
                  timer.schedule(myThreadA,new Date(nowTime),3000);
                  timer.schedule(myThreadB,new Date(nowTime),3000);
              }
          結(jié)果:
          當(dāng)前時(shí)間:1616916022030
          計(jì)劃時(shí)間為:1616916022030
          A run time=1616916022035
          A任務(wù)將自己移除
          B run time=1616916022035
          B run time=1616916025041
          B run time=1616916028061


          Timer類中的cancel()方法

          Timer類中的cancel()方法作用是將任務(wù)隊(duì)列中所有任務(wù)清除。該方法的源代碼如下

          public void cancel() {
                  synchronized(queue) {
                      thread.newTasksMayBeScheduled = false;
                      queue.clear();
                      queue.notify();  // In case queue was already empty.
                  }
              }

          public class MyThreadA extends TimerTask {
              @Override
              public void run() {
                  System.out.println("A run time="+System.currentTimeMillis());
              }
          }
          class MyThreadB extends TimerTask{
              @Override
              public void run() {
                  System.out.println("B run time="+System.currentTimeMillis());
              }
          }
          class test{
              public static void main(String[] args) throws Exception{
                  long nowTime=System.currentTimeMillis();
                  System.out.println("當(dāng)前時(shí)間:"+nowTime);
                  System.out.println("計(jì)劃時(shí)間為:"+nowTime);
                  MyThreadB myThreadB = new MyThreadB();
                  MyThreadA myThreadA = new MyThreadA();
                  Timer timer = new Timer();
                  timer.schedule(myThreadA,new Date(nowTime),4000);
                  timer.schedule(myThreadB,new Date(nowTime),4000);
                  Thread.sleep(10000);
                  timer.cancel();
                  System.out.println("任務(wù)全部取消了");
              }
          }
          結(jié)果:
          當(dāng)前時(shí)間:1616916352810
          計(jì)劃時(shí)間為:1616916352810
          A run time=1616916352810
          B run time=1616916352810
          B run time=1616916356818
          A run time=1616916356818
          A run time=1616916360820
          B run time=1616916360820
          任務(wù)全部取消了


          Timer類中的cancel方法有時(shí)候不一定會(huì)停止計(jì)劃任務(wù),即任務(wù)正常執(zhí)行。

          其原因是沒(méi)有搶到queue鎖,導(dǎo)致TimerTask中的任務(wù)正常執(zhí)行。

          public class MyTask extends TimerTask {
              private int i;

              public MyTask(int i) {
                  this.i = i;
              }

              @Override
              public void run() {
                  System.out.println("第"+i+"次沒(méi)有被取消");
              }
          }
           class tests{
               public static void main(String[] args) {
                   int i=0;
                   long nowTime=System.currentTimeMillis();
                   System.out.println("當(dāng)前時(shí)間:"+nowTime);
                   System.out.println("計(jì)劃時(shí)間為:"+nowTime);
                   while (true){
                       i++;
                       Timer timer = new Timer();
                       MyTask myTask = new MyTask(i);
                       timer.schedule(myTask,new Date(nowTime));
                       timer.cancel();
                   }
               }
           }
           結(jié)果:
          當(dāng)前時(shí)間:1616921790699
          計(jì)劃時(shí)間為:1616921790699
          第123次沒(méi)有被取消
          第12802次沒(méi)有被取消

          間隔執(zhí)行Task任務(wù)的算法

          當(dāng)隊(duì)列中有3個(gè)任務(wù)ABC時(shí)這三個(gè)任務(wù)執(zhí)行的順序的算法是每次將最后一個(gè)任務(wù)放入隊(duì)頭,再執(zhí)行隊(duì)頭中的方法。其執(zhí)行順序效果如下:

          1)ABC;

          2)CAB;將C放入AB之前

          3)BCA;將B放入CA之前

          驗(yàn)證如下:

          public class MyThreadA extends TimerTask {
              @Override
              public void run() {
                  System.out.println("A run time="+System.currentTimeMillis());
              }
          }
          class MyThreadB extends TimerTask{
              @Override
              public void run() {
                  System.out.println("B run time="+System.currentTimeMillis());
              }
          }
          class MyThreadC extends TimerTask{
              @Override
              public void run() {
                  System.out.println("C run time="+System.currentTimeMillis());
              }
          }
          class test{
              public static void main(String[] args) throws Exception{
                  long nowTime=System.currentTimeMillis();
                  System.out.println("當(dāng)前時(shí)間:"+nowTime);
                  System.out.println("計(jì)劃時(shí)間為:"+nowTime);
                  MyThreadA myThreadA = new MyThreadA();
                  MyThreadB myThreadB = new MyThreadB();
                  MyThreadC myThreadC = new MyThreadC();
                  Timer timer = new Timer();
                  timer.schedule(myThreadA,new Date(nowTime),2000);
                  timer.schedule(myThreadB,new Date(nowTime),2000);
                  timer.schedule(myThreadC,new Date(nowTime),2000);

                  Thread.sleep(Integer.MAX_VALUE);
              }
          }
          測(cè)試結(jié)果:
          當(dāng)前時(shí)間:1616917048998
          計(jì)劃時(shí)間為:1616917048998
          A run time=1616917049005
          B run time=1616917049005
          C run time=1616917049005
          C run time=1616917051005
          A run time=1616917051005
          B run time=1616917051005
          B run time=1616917053006
          C run time=1616917053006
          A run time=1616917053006


          schedule(TimerTask task, long delay)

          schedule(TimerTask task, long delay) 該方法的作用是以當(dāng)前的時(shí)間為參考時(shí)間在此時(shí)間上加上指定的延遲時(shí)間。

          public class Run {
              static public class myTask extends TimerTask{
                  @Override
                  public void run() {
                      System.out.println("開(kāi)始運(yùn)行了,時(shí)間為:"+System.currentTimeMillis());
                  }
              }
              public static void main(String[] args) {
                  myTask myTask = new myTask();
                  Timer timer = new Timer();
                  System.out.println("當(dāng)前時(shí)間:"+System.currentTimeMillis());
                  timer.schedule(myTask,5000);
              }
          }
          結(jié)果:
          當(dāng)前時(shí)間:1616922170729
          開(kāi)始運(yùn)行了,時(shí)間為:1616922175739

          運(yùn)行時(shí)間被延遲了5秒。


          schedule(TimerTask task, long delay, long period)

          schedule(TimerTask task, long delay, long period)該方法的作用是以當(dāng)前的時(shí)間為參考時(shí)間在此時(shí)間上加上指定的延遲時(shí)間,在以此時(shí)間間隔上無(wú)限的執(zhí)行某一任務(wù)。

          public class Run {
              static public class myTask extends TimerTask{
                  @Override
                  public void run() {
                      System.out.println("開(kāi)始運(yùn)行了,時(shí)間為:"+System.currentTimeMillis());
                  }
              }
              public static void main(String[] args) {
                  myTask myTask = new myTask();
                  Timer timer = new Timer();
                  System.out.println("當(dāng)前時(shí)間:"+System.currentTimeMillis());
                  timer.schedule(myTask,5000,2000);
              }
          }
          結(jié)果:
          當(dāng)前時(shí)間:1616922425863
          開(kāi)始運(yùn)行了,時(shí)間為:1616922430879
          開(kāi)始運(yùn)行了,時(shí)間為:1616922432879
          開(kāi)始運(yùn)行了,時(shí)間為:1616922434899
          開(kāi)始運(yùn)行了,時(shí)間為:1616922436909

          scheduleAtFixedRate方法

          scheduleAtFixedRate(TimerTask task, long delay, long period)該方法與 schedule(TimerTask task, long delay, long period) 這兩個(gè)方法的用法大致是一樣的。


          scheduleAtFixedRate(TimerTask task, Date firstTime, long period)該方法與 schedule(TimerTask task, Date firstTime, long period) 這兩個(gè)方法的用法大致是一樣的。

          但是他們之間也是有區(qū)別的。他們之間的區(qū)別就是是否具有追趕性。下面我們用兩個(gè)案例來(lái)測(cè)試他們的追趕性。

          驗(yàn)證schedule()方法 不具有追趕性

          public class Test6 {
              static public class myTask extends TimerTask {
                  @Override
                  public void run() {
                      System.out.println("begin time:"+System.currentTimeMillis());
                      System.out.println("end time:"+System.currentTimeMillis());
                  }
              }
              public static void main(String[] args) {
                  myTask myTask = new myTask();
                  Timer timer = new Timer();
                  long nowTime=System.currentTimeMillis();
                  System.out.println("當(dāng)前時(shí)間:"+nowTime);
                  long runTime=nowTime-10000;
                  System.out.println("現(xiàn)在計(jì)劃執(zhí)行時(shí)間:"+runTime);
                  timer.schedule(myTask,new Date(runTime),2000);
              }
          }
          結(jié)果;
          當(dāng)前時(shí)間:1616923764405
          現(xiàn)在計(jì)劃執(zhí)行時(shí)間:1616923754405
          begin time:1616923764405
          end time:1616923764405
          begin time:1616923766406
          end time:1616923766406
          begin time:1616923768423
          end time:1616923768423
          begin time:1616923770426
          end time:1616923770426
          begin time:1616923772446
          end time:1616923772446


          從結(jié)果來(lái)看1616923754405時(shí)間到1616923764405這一時(shí)間的任務(wù)都沒(méi)有被執(zhí)行,這說(shuō)明schedule()方法不具有追趕性。

          驗(yàn)證scheduleAtFixedRate()方法具有追趕性

          public class Test6 {
              static public class myTask extends TimerTask {
                  @Override
                  public void run() {
                      System.out.println("begin time:"+System.currentTimeMillis());
                      System.out.println("end time:"+System.currentTimeMillis());
                  }
              }
              public static void main(String[] args) {
                  myTask myTask = new myTask();
                  Timer timer = new Timer();
                  long nowTime=System.currentTimeMillis();
                  System.out.println("當(dāng)前時(shí)間:"+nowTime);
                  long runTime=nowTime-10000;
                  System.out.println("現(xiàn)在計(jì)劃執(zhí)行時(shí)間:"+runTime);
                  timer.scheduleAtFixedRate(myTask,new Date(runTime),2000);
              }
          }
          結(jié)果:
          當(dāng)前時(shí)間:1616924118955
          現(xiàn)在計(jì)劃執(zhí)行時(shí)間:1616924108955
          begin time:1616924118955
          end time:1616924118955
          begin time:1616924118955
          end time:1616924118955
          begin time:1616924118955
          end time:1616924118955
          begin time:1616924118955
          end time:1616924118955
          begin time:1616924118955
          end time:1616924118955
          begin time:1616924118955
          end time:1616924118955
          begin time:1616924120956
          end time:1616924120956
          begin time:1616924122955
          end time:1616924122955
          begin time:1616924124956
          end time:1616924124956
          begin time:1616924126955
          end time:1616924126955

          輸出時(shí)間1616924118955都是曾經(jīng)流逝時(shí)間的任務(wù)追趕,也就是將之前任務(wù)沒(méi)有執(zhí)行的任務(wù)追加執(zhí)行,將這10秒之內(nèi)的任務(wù)次數(shù)輸出完,再每間隔2秒執(zhí)行一次任務(wù)。將這兩段時(shí)間所對(duì)應(yīng)的任務(wù)彌補(bǔ)執(zhí)行,也就是在指定時(shí)間段內(nèi)的運(yùn)行次數(shù)必須運(yùn)行完整,這就是Task任務(wù)的追趕性。

          ————————————————

          版權(quán)聲明:本文為CSDN博主「程序員小汪」的原創(chuàng)文章,遵循CC 4.0 BY-SA版權(quán)協(xié)議,轉(zhuǎn)載請(qǐng)附上原文出處鏈接及本聲明。

          原文鏈接:

          https://blog.csdn.net/weixin_44991304/article/details/115256074




          鋒哥最新SpringCloud分布式電商秒殺課程發(fā)布

          ??????

          ??長(zhǎng)按上方微信二維碼 2 秒





          感謝點(diǎn)贊支持下哈 

          瀏覽 47
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  国产69精品久久久久久久久久久久 | 国产区在线观看 | 俺也去色网 | 一级a一级a爰片免费免免在线 | 韩国一级中文无码 |