乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      4.定時調(diào)度類Timer和TimerTask

       印度阿三17 2020-03-10

      一.概述

      • 在日常開發(fā)中我們經(jīng)常執(zhí)行定時任務(wù),此時我們可以使用守護線程或者是Timer類,此處我們避免守護線程使用的繁瑣就使用Timer類

      1.Timer類和TimerTask類

      • 在java.util包下

      • Timer類:實現(xiàn)線程任務(wù)調(diào)度

        • ?void schedule(TimerTask task, long delay, long period) ?:在指定的延遲之后開始 ,重新執(zhí)行固定延遲執(zhí)行的指定任務(wù)。

        • ?void schedule(TimerTask task, long delay) ?:在指定的延遲之后安排指定的任務(wù)執(zhí)行。?

      • TimerTask類:實現(xiàn)定時處理任務(wù)的接口,我們需要實現(xiàn)此接口來完成定時任務(wù)

      ?轉(zhuǎn)載:https://www.cnblogs.com/xsjzhao/p/10651704.html

      1 關(guān)于 (時間寶貴的請?zhí)^)

      • 什么是定時任務(wù)調(diào)度
        基于給定的時間點,給定的時間間隔或者給定的執(zhí)行次數(shù)自動執(zhí)行的任務(wù)。
      • 在Java中的定時調(diào)度工具
        • Timer
        • Quartz
      • 兩者主要區(qū)別
        1. 出身上,Timer是Java提供的原生Scheduler(任務(wù)調(diào)度)工具類,不需要導(dǎo)入其他jar包;而Quartz是OpenSymphony開源組織在任務(wù)調(diào)度領(lǐng)域的一個開源項目,完全基于Java實現(xiàn)。
        2. 功能上,如需要實現(xiàn)在某個具體時間執(zhí)行什么任務(wù)的話,Timer足以勝任;如需要實現(xiàn)每個星期六8點鬧鐘提醒之類的復(fù)雜任務(wù),就需要用Quartz。因此,Quartz在時間控制上的功能遠比Timer強大和完善。
        3. 底層上,Timer使用一個后臺線程去執(zhí)行定時任務(wù),Quartz擁有后臺線程執(zhí)行池(類比JDBC連接池),能夠使用多個執(zhí)行線程去執(zhí)行定時任務(wù)。

      簡而言之,Quartz > Timer,Timer是被動地根據(jù)既定時間去調(diào)度任務(wù)的,Quartz則是自己主動定制時間規(guī)則去支持更加豐富地調(diào)度方法。
      本文主要是講解Timer工具類的,故而下文中不會過多討論Quartz。

      • 前導(dǎo)知識
      Timer, Quartz的使用Quartz, Spring的整合
      Java編程知識 Spring基礎(chǔ)知識

      2 Timer簡介和配套視頻課程

      Timer類位于java.util包下,有關(guān)Timer類的詳細描述信息請點擊這里訪問Oracle Java的官方api文檔查閱。

      Timer工具類圖是Timer工具類及有關(guān)類的類圖。
      Timer工具類圖

      快速開始:

      /*
       * Foo.java -- JDK 1.8
       */
      
      package timer;
      
      import java.util.Timer;
      import java.util.TimerTask;
      
      /**
       * Description:
       * <p>
       * <p>
       * @author ascribed
       * @date 2019-04-03 Wed PM 19:15:08
       */
      
      public class Foo {  
          public static void main(String[] args) {
              Timer timer = new Timer(); // 1. 創(chuàng)建Timer實例,關(guān)聯(lián)線程不能是daemon(守護/后臺)線程
              FooTimerTask fooTimerTask = new FooTimerTask(); // 2. 創(chuàng)建任務(wù)對象
              timer.schedule(fooTimerTask, 3000L, 2000L); // 3. 通過Timer定時定頻率調(diào)用fooTimerTask的業(yè)務(wù)代碼
          }
      }
      
      class FooTimerTask extends TimerTask {
          @Override
          public void run() {
              // TODO 業(yè)務(wù)代碼......
              System.out.println("Hello Timer!");
          }
      }

      3 Timer函數(shù)和綜合運用

      3.1 Timer定時函數(shù)的用法

      注意:Timer類在時間granularity(粒度)是毫秒級的,實際上Timer的schedule系列方法獲取時間的方式是System.currentTimeMillis()(當(dāng)前時間與Unix元年之差,類型為long),最多只能到毫秒級,而一些操作系統(tǒng)的計時精度會達到1/10毫秒。

      3.1.1 schedule()方法的4種用法

      1. schedule(TimerTask task, Date time)
        作用
        在時間等于或超過time的時候執(zhí)行且僅執(zhí)行一次task (單次)。
        源碼
          public void schedule(TimerTask task, Date time) {
              sched(task, time.getTime(), 0);
          }
      1. schedule(TimerTask task, Date firstTime, long period)
        作用
        時間等于或超過firstTime時首次執(zhí)行task,之后每隔peroid毫秒重復(fù)執(zhí)行一次task (多次)。
        源碼
          public void schedule(TimerTask task, long delay, long period) {
              if (delay < 0)
                  throw new IllegalArgumentException("Negative delay.");
              if (period <= 0)
                  throw new IllegalArgumentException("Non-positive period.");
              sched(task, System.currentTimeMillis() delay, -period);
          }
      1. schedule(TimerTask task, long delay)
        作用
        等待delay毫秒后執(zhí)行且僅執(zhí)行一次task (單次)。
        源碼
          public void schedule(TimerTask task, long delay) {
              if (delay < 0)
                  throw new IllegalArgumentException("Negative delay.");
              sched(task, System.currentTimeMillis() delay, 0);
          }
      1. schedule(TimerTask task, long delay, long period)
        作用
        等待delay毫秒后首次執(zhí)行task, 之后每個period毫秒重復(fù)執(zhí)行一次task (多次)。
        源碼
          public void scheduleAtFixedRate(TimerTask task, long delay, long period) {
              if (delay < 0)
                  throw new IllegalArgumentException("Negative delay.");
              if (period <= 0)
                  throw new IllegalArgumentException("Non-positive period.");
              sched(task, System.currentTimeMillis() delay, period);
          }

      3.1.2 scheduleAfixRate()的2種用法

      1. scheduleAtFixedRate(TimerTask task, Date firstTime, long period)
        作用
        時間等于或超過time時首次執(zhí)行task,之后每隔peroid毫秒重復(fù)執(zhí)行一次task (多次, 同schedule第2種用法)。
        源碼
          public void scheduleAtFixedRate(TimerTask task, long delay, long period) {
              if (delay < 0)
                  throw new IllegalArgumentException("Negative delay.");
              if (period <= 0)
                  throw new IllegalArgumentException("Non-positive period.");
              sched(task, System.currentTimeMillis() delay, period);
          }
      1. scheduleAtFixedRate(TimerTask task, long delay, long period)
        作用
        等待delay毫秒后首次執(zhí)行task, 之后每個period毫秒重復(fù)執(zhí)行一次task (多次, 同schedule第4種用法)。
        源碼
          public void scheduleAtFixedRate(TimerTask task, Date firstTime, long period) {
              if (period <= 0)
                  throw new IllegalArgumentException("Non-positive period.");
              sched(task, firstTime.getTime(), period);
          }

      筆記:

      1. schedule()和scheduleAtFixedRate()方法都能實現(xiàn)對任務(wù)的一次或多次調(diào)度。
      2. schedule()按是否可重復(fù)執(zhí)行分為單次和多次,按任務(wù)初次執(zhí)行計算方式分為delay(long型延遲毫秒數(shù))和time(Date型時間)。
      3. schedule()和scheduleAtFixedRate()最終都是調(diào)用Timer類下的sched()方法實現(xiàn)的。
        演示代碼包含DemoTimer.java和TimerUtils.java,代碼清單:
      /*
       * DemoTimer.java -- JDK 1.8
       */
      
      package timer;
      
      import java.util.Calendar;
      import java.util.Timer;
      import java.util.TimerTask;
      
      /**
       * Description:
       * <p>
       * <p>
       * @author ascribed
       * @date 2019-04-03 Wed PM 18:37:03
       */
      
      public class DemoTimer {
          public static void main(String[] args) {
              Calendar calendar = TimerUtils.current();
              TimerUtils.miscellaneous("Current time is : ", calendar.getTime());
              calendar.add(Calendar.SECOND, 3); // 當(dāng)前時間加3秒
      
              Timer timer = new Timer(); 
              DemoTimerTask demoTimerTask = new DemoTimerTask("No. 1"); 
              
              demoTimerTask.setName("schedule1"); 
              timer.schedule(demoTimerTask, calendar.getTime()); // 3.1.1.1
              
      //        demoTimerTask.setName("schedule2");
      //        timer.schedule(demoTimerTask, calendar.getTime(), 2000); // 3.1.1.2
      //        
      //        demoTimerTask.setName("schedule3");
      //        timer.schedule(demoTimerTask, 3000); // 3.1.1.3
      //        
      //        demoTimerTask.setName("schedule4");
      //        timer.schedule(demoTimerTask, 3000, 2000); // 3.1.1.4
      //        
      //        demoTimerTask.setName("scheduleAtFixedRate1");
      //        timer.scheduleAtFixedRate(demoTimerTask, calendar.getTime(), 2000); // 3.1.2.1
      //        
      //        demoTimerTask.setName("scheduleAtFixedRate2"); 
      //        timer.scheduleAtFixedRate(demoTimerTask, 3000, 2000); // 3.1.2.2
          }
      }
      
      class DemoTimerTask extends TimerTask {
      
          String name; // 任務(wù)名
      
          public DemoTimerTask(String name) {
              this.name = name;
          }
      
          @Override
          public void run() {
              TimerUtils.miscellaneous("Current time is : ", TimerUtils.current().getTime());
              System.out.println("Current exec name is : "   name); // 打印當(dāng)前name的內(nèi)容
          }
      
          public String getName() {
              return name;
          }
      
          public void setName(String name) {
              this.name = name;
          }
      }
      
      /*
       * TimerUtils.java -- JDK 1.8
       */
      
      package timer;
      
      import java.text.SimpleDateFormat;
      import java.util.Calendar;
      import java.util.Date;
      import java.util.TimerTask;
      
      /**
       * Description:
       * <p>
       * <p>
       * @author ascribed
       * @date 2019-04-03 Wed PM 18:40:26
       */
      
      public class TimerUtils {
          final static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); // 定義日期格式
          static Calendar current() {
              Calendar calendar = Calendar.getInstance(); // 通過靜態(tài)工廠方法創(chuàng)建Calendar實例
              return calendar;
          }
          static void schedtime(TimerTask task) {
              System.out.println("scheduled time is "   sdf.format(task.scheduledExecutionTime()));
          }
          
          static void miscellaneous(String str, Date date) {
              System.out.println(str   sdf.format(date));
          }
      }

      3.2 其他重要函數(shù)

      3.2.1 TimerTask的cancel(), scheduledExecutionTime()

      1. cancel()
        作用
        終止此計時器,丟棄所有當(dāng)前已安排(scheduled)的任務(wù)。
        說明
        通過查看源碼,TimerTask的實現(xiàn)機制是通過設(shè)置標(biāo)志位來記錄timer task的狀態(tài),調(diào)用cancel()方法的timer task實例并沒有從相應(yīng)TaskQueue隊列移除,這是和Timer類的cancel()方法不同之處。
        源碼
          public boolean cancel() {
              synchronized(lock) {
                  boolean result = (state == SCHEDULED);
                  state = CANCELLED;
                  return result;
              }
          }
          
      
      1. scheduledExecutionTime()
        作用
        從此計時器的任務(wù)隊列中移除所有已取消(canceled)的任務(wù)。
        返回值
        從隊列中移除的任務(wù)數(shù)。
        源碼
          public long scheduledExecutionTime() {
              synchronized(lock) {
                  return (period < 0 ? nextExecutionTime   period
                                     : nextExecutionTime - period);
              }
          }

      不能與fixed-delay執(zhí)行式的重復(fù)任務(wù)搭配使用,也就是不用于schedule方法,應(yīng)為schedule方法的(scheduled execution time)計劃執(zhí)行時間會偏移理想的計劃時間,對她使用這個方法沒有無意義。
      演示代碼清單:

      /*
       * CancelTest.java -- JDK 1.8
       */
      
      package timer;
      
      import java.util.Timer;
      import java.util.TimerTask;
      
      /**
       * Description:
       * <p>
       * <p>
       * @author ascribed
       * @date 2019-04-03 Wed PM 19:43:04
       */
      
      public class CancelTest {
          public static void main(String[] args) {
              Timer timer = new Timer();
              MyTimerTask myTimerTask = new MyTimerTask("schedule");
              TimerUtils.miscellaneous("Current time is : ", TimerUtils.current().getTime());
              timer.schedule(myTimerTask, 3000, 2000); // 3.2.1
      //        timer.schedule(myTimerTask, 3000); // 3.3.2
      //        TimerUtils.schedtime(myTimerTask);
          }
      }
      class MyTimerTask extends TimerTask {
          private String name;
          private Integer count = 0;
          
          public MyTimerTask(String name) {
              this.name = name;
          }
      
          @Override
          public void run() {
              if (count < 3) {
                  TimerUtils.miscellaneous("Current time is : ", TimerUtils.current().getTime());
                  System.out.println("Current exec name is : "   name);
                  count  ;
              } else {
                  cancel();
                  System.out.println("Task canceled");
                  System.exit(0);
              }
          }
      
          public String getName() {
              return name;
          }
      
          public void setName(String name) {
              this.name = name;
          }
      }

      3.2.2 Timer的cancel(), purge()

      1. cancel()
        作用
        終止此計時器,丟棄所有當(dāng)前已安排的任務(wù)。
        源碼
          public void cancel() {
              synchronized(queue) {
                  thread.newTasksMayBeScheduled = false;
                  queue.clear();
                  queue.notify();  // 防止隊列已為空的處理
              }
          }
      1. purge()
        作用
        purge,意為凈化;(將不需要的東西)從......清除,相比消滅顯得優(yōu)雅一些。從此計時器的任務(wù)隊列中移除所有已取消的任務(wù)。
        返回值
        從隊列中移除的任務(wù)數(shù)。
        源碼
           public int purge() {
               int result = 0;
      
               synchronized(queue) {
                   for (int i = queue.size(); i > 0; i--) {
                       if (queue.get(i).state == TimerTask.CANCELLED) {
                           queue.quickRemove(i);
                           result  ;
                       }
                   }
      
                   if (result != 0)
                       queue.heapify();
               }
      
               return result;
           }
      }

      演示代碼:

      /*
       * CancelTest.java -- JDK 1.8
       */
      
      package timer;
      
      import java.util.Date;
      import java.util.Timer;
      import java.util.TimerTask;
      
      /**
       * Description:
       * <p>
       * <p>
       * @author ascribed
       * @date 2019-04-03 Wed PM 19:43:04
       */
      
      public class CancelTest {
          public static void main(String[] args) throws InterruptedException {
              Timer timer = new Timer();
              MyTimerTask task1 = new MyTimerTask("task1");
              MyTimerTask task2 = new MyTimerTask("task2");
              TimerUtils.miscellaneous("start time is : ", new Date());
              // task1首次執(zhí)行是距離現(xiàn)在時間2秒后,之后每隔2秒執(zhí)行一次
              // task2首次執(zhí)行是距離現(xiàn)在時間1秒后,之后每隔2秒執(zhí)行一次
              timer.schedule(task1, 1000, 2000); // 奇數(shù)次執(zhí)行
              timer.schedule(task2, 2000, 2000); // 偶數(shù)次執(zhí)行
      //        System.out.println("current canceled task number is : "   timer.purge());
              Thread.sleep(5000); // 當(dāng)前線程休眠5秒后cancel生效,沒有此句立即觸發(fā)cancel
              TimerUtils.miscellaneous("cancel time is : ", new Date());
              /*3.2.2.1
              下面兩句執(zhí)行完后程序只剩下后臺線程,JRE判定當(dāng)前程序結(jié)束
              因為當(dāng)前程序只有后臺線程,所有前臺線程結(jié)束,后臺的工作無前臺線程使用就是沒有意義的
               */
              timer.cancel(); // 當(dāng)前線程若檢測到timer對隊列中的任務(wù)進行調(diào)度則終止timer并從任務(wù)隊列移除所有任務(wù)
              System.out.println("Tasks all canceled!"); // 若此句輸出后看到還有任務(wù)運行則停止所有運行的程序,這可能是之前運行的程序未終止
              // 3.2.2.2
      //        task1.cancel(); // 當(dāng)前線程每次檢測到timer對task1進行schedule取消task1
      //        System.out.println("current canceled task number is : "   timer.purge());
          }
      }
      
      class MyTimerTask extends TimerTask {
          private String name;
          private Integer count = 0;
      
          public MyTimerTask(String name) {
              this.name = name;
          }
      
          @Override
          public void run() {
              if (count < 3) {
                  TimerUtils.miscellaneous("Current time is : ", TimerUtils.current()
                          .getTime());
                  System.out.println("Current exec name is : "   name);
                  count  ;
              } else {
                  cancel();
                  System.out.println("Task canceled");
                  System.exit(0);
              }
          }
      
          public String getName() {
              return name;
          }
      
          public void setName(String name) {
              this.name = name;
          }
      }

      3.3 schedule()和scheduledAtFixedRate()的區(qū)別

      兩種情況看區(qū)別一覽表

      方法schedulescheduleAtFixedRate
      首次計劃執(zhí)行時間早于當(dāng)前時間 "fixed-delay",用代碼的形式理解就是scheduleAtfixedDelay();如果第一次執(zhí)行時間被delay了,隨后的執(zhí)行時間按照上一次實際執(zhí)行完成的時間點進行計算。 "fixed-rate",義如其名;如果第一次執(zhí)行時間按照上一次開始的時間點進行計算,并且為了趕上進度會多次執(zhí)行任務(wù),因此TimerTask中的執(zhí)行體需要考慮同步。
      任務(wù)執(zhí)行所需的時間超出任務(wù)的執(zhí)行周期間隔 下一次執(zhí)行時間相對于上一次實際執(zhí)行完成的時間點,因此執(zhí)行時間會不斷延后 下一次執(zhí)行時間相對于上一次開始的時間點,因此執(zhí)行時間一般不會延后,因此存在并發(fā)性

      fixed-delay和fixed-rate執(zhí)行的區(qū)別

      1. 對于fixed-delay執(zhí)行講解:
        如當(dāng)前時間2020-01-01 00:01:00,period為2000毫秒,將開始執(zhí)行時間提前6秒即2020-01-01 00:01:57秒,首次執(zhí)行時間為2020-01-01 00:01:00而不是2020-01-01 00:01:57,代碼snippet:
              Calendar calendar = Calendar.getInstance();
              calendar.add(Calendar.SECOND, -6); // L1
              Timer timer = new Timer();
              // 第一次執(zhí)行為6秒前,之后么個兩秒鐘執(zhí)行一次
              timer.schedule(new TimerTask() {
                  @Override
                  public void run() { // L2
                      System.out.println("Scheduled exec time is : "   TimerUtils.sdf.format(scheduledExecutionTime()));
                      System.out.println("Task is being executed!");
                  }
              }, calendar.getTime(), 2000);

      如果任務(wù)時間為3000毫秒,第一次執(zhí)行開始時間2020-01-01 00:01:00,第二次為2020-01-01 00:01:03而不是2020-01-01 00:01:02。
      這里使用在任務(wù)線程休眠三秒來實現(xiàn),注釋掉L1行代碼,在L1處添加代碼休眠三秒,代碼snippet:

              Calendar calendar = Calendar.getInstance();
              Timer timer = new Timer();
              timer.schedule(new TimerTask() {
                  @Override
                  public void run() {
                      try {
                          Thread.sleep(3000);
                      } catch (InterruptedException e) {
                          e.printStackTrace();
                      }
                      System.out.println("Scheduled exec time is : "   TimerUtils.sdf.format(scheduledExecutionTime()));
                      System.out.println("Task is being executed!");
                  }
              }, calendar.getTime(), 2000);
      1. 對于fixed-reate執(zhí)行講解:
        如當(dāng)前時間2019-04-03 23:02:58,period為2000毫秒,將開始執(zhí)行時間提前6秒即2019-04-03 23:02:52秒,首次執(zhí)行時間為2019-04-03 23:02:52,控制臺會看到開始會一下子執(zhí)行如下4次任務(wù):
      Current time is : 2019-04-03 23:02:58
      Scheduled exec time is : 2019-04-03 23:02:52
      Task is being executed!
      Scheduled exec time is : 2019-04-03 23:02:54
      Task is being executed!
      Scheduled exec time is : 2019-04-03 23:02:56
      Task is being executed!
      Scheduled exec time is : 2019-04-03 23:02:58
      Task is being executed!

      代碼snippet:

              Calendar calendar = Calendar.getInstance();
              calendar.add(Calendar.SECOND, -6); // L1
              Timer timer = new Timer();
              timer.scheduleAtFixedRate(new TimerTask() {
                  @Override
                  public void run() {// L3
                      System.out.println("Scheduled exec time is : "   TimerUtils.sdf.format(scheduledExecutionTime()));
                      System.out.println("Task is being executed!");
                  }
              }, calendar.getTime(), 2000); 
          }

      如果任務(wù)時間為3000毫秒,period為2000毫秒,當(dāng)前時間2019-04-03 23:23:22,第一次執(zhí)行開始時間2019-04-03 23:23:22,第二次執(zhí)行時間2019-04-03 23:23:24,兩個任務(wù)執(zhí)行時間段有交集。
      注釋掉L1所在行,在L3處讓任務(wù)線程休眠三秒模仿執(zhí)行時間為3秒的任務(wù),代碼snippet:

              Calendar calendar = Calendar.getInstance();
              calendar.add(Calendar.SECOND, -6); // L1
              Timer timer = new Timer();
              timer.scheduleAtFixedRate(new TimerTask() {
                  @Override
                  public void run() {
                      try {
                          Thread.sleep(3000); // L3
                      } catch (InterruptedException e) {
                          e.printStackTrace();
                      }
                      System.out.println("Scheduled exec time is : "   TimerUtils.sdf.format(scheduledExecutionTime()));
                      System.out.println("Task is being executed!");
                  }
              }, calendar.getTime(), 2000);

      注釋掉不需要的代碼觀察效果,演示代碼:

      /*
       * DifferenceTest.java -- JDK 1.8
       */
      
      package timer;
      
      import java.util.Calendar;
      import java.util.Timer;
      import java.util.TimerTask;
      
      /**
       * Description:
       * <p>
       * <p>
       * @author ascribed
       * @date 2019-04-03 Wed PM 21:47:38
       */
      
      public class DifferenceTest {
      
          public static void main(String[] args) {
              Calendar calendar = TimerUtils.current();
              TimerUtils.miscellaneous("Current time is : ", calendar.getTime());
              // 設(shè)置成6秒前的時間,若當(dāng)前時間為2016-12-28 00:00:06
              // 那么設(shè)置之后時間變成2016-12-28 00:00:00
              calendar.add(Calendar.SECOND, -6); // L1
              Timer timer = new Timer();
              // 第一次執(zhí)行為6秒前,之后么個兩秒鐘執(zhí)行一次
              timer.schedule(new TimerTask() {
                  @Override
                  public void run() {
                      try {
                          Thread.sleep(3000); // L2
                      } catch (InterruptedException e) {
                          e.printStackTrace();
                      }
                      System.out.println("Scheduled exec time is : "   TimerUtils.sdf.format(scheduledExecutionTime()));
                      System.out.println("Task is being executed!");
                  }
              }, calendar.getTime(), 2000); // 此處有個語法糖,編譯器生成一個匿名類繼承抽象類TimerTask通過new實例化,這并不違反抽象類不能實例化這一原則
              
              timer.scheduleAtFixedRate(new TimerTask() {
                  @Override
                  public void run() {
                      try {
                          Thread.sleep(3000);  // L3
                      } catch (InterruptedException e) {
                          e.printStackTrace();
                      }
                      System.out.println("Scheduled exec time is : "   TimerUtils.sdf.format(scheduledExecutionTime()));
                      System.out.println("Task is being executed!");
                  }
              }, calendar.getTime(), 2000); 
          }
      
      }

      4 實戰(zhàn)

      實現(xiàn)兩個機器人
      跳舞機器人:每隔兩秒打印最近一次計劃的時間和執(zhí)行內(nèi)容
      灌水機器人:模擬往桶里倒水,直到桶里的水滿為止
      灌水機器人工作流程
      灌水,如果水不滿,則一直工作;如果水滿,則停止工作。
      跳舞機器人
      跳舞,如果水不滿,則一直工作;如果水滿,則跳舞兩秒后停止工作。
      代碼清單
      DancingRobot.java、WaterRobot.java和Executor.java。

      /*
       * WaterRobot.java -- JDK 1.8
       */
      
      package timer;
      
      import java.util.Timer;
      import java.util.TimerTask;
      
      /**
       * Description:
       * <p>
       * <p>
       * @author ascribed
       * @date 2019-04-02 Tue PM 16:44:17
       */
      
      public class WaterRobot extends TimerTask {
          
          private Timer timer;
          // 最大容量5L
          private Integer bucketCapacity = 0;
          private final String unit = "L";
          public WaterRobot(Timer timer) {
              this.timer = timer;
          }  
          
          @Override
          public void run() {
              // 灌水到桶滿為止
              if (bucketCapacity < 5) {
                  System.out.println("Add 1L water into the bucket!");
                  bucketCapacity  ;
              } else {
                  // 水滿之后停止執(zhí)行
                  System.out.println("The number of canceled task in timer is : "   timer.purge());
                  cancel();
                  System.out.println("The waterRot has been aborted");
                  System.out.println("The number of canceled task in timer is : "   timer.purge());
                  System.out.println("Current water is "   bucketCapacity   unit);
                  // 等待兩秒鐘,終止timer里面的所有內(nèi)容
                  try {
                      Thread.sleep(2000);
                  } catch (InterruptedException e) {
                      e.printStackTrace();
                  }
                  timer.cancel();
              }
          }
      }
      /*
       * DancingRobot.java -- JDK 1.8
       */
      
      package timer;
      
      import java.text.SimpleDateFormat;
      import java.util.TimerTask;
      
      /**
       * Description:
       * <p>
       * <p>
       * @author ascribed
       * @date 2019-04-02 Tue PM 16:35:12
       */
      
      public class DancingRobot extends TimerTask {
      
          @Override
          public void run() {
              SimpleDateFormat sdf = new SimpleDateFormat(TimeConstants.DATE_FORMAT);
              System.out.println("Scheduled exec time is : "   sdf.format(scheduledExecutionTime())); // 獲得最近一次任務(wù)執(zhí)行的計劃時間
              System.out.println("Dancing happily!");
          }
      
      }
      /*
       * Executor.java -- JDK 1.8
       */
      
      package timer;
      
      import java.text.SimpleDateFormat;
      import java.util.Calendar;
      import java.util.Timer;
      
      /**
       * Description:
       * <p>
       * <p>
       * @author ascribed
       * @date 2019-04-02 Tue PM 16:54:04
       */
      
      public class Executor {
      
          public static void main(String[] args) {
              Timer timer = new Timer(); 
              Calendar calendar = Calendar.getInstance();
              SimpleDateFormat sdf = new SimpleDateFormat(TimeConstants.DATE_FORMAT);
              System.out.println("Current time is : "   sdf.format(calendar.getTime()));
              
              DancingRobot dr = new DancingRobot();
              WaterRobot wr = new WaterRobot(timer);
              
              timer.schedule(dr, calendar.getTime(), 2000);
              timer.scheduleAtFixedRate(wr, calendar.getTime(), 1000);
          }
      
      }

      執(zhí)行結(jié)果

      Current time is : 2019-04-04 01:19:20
      Scheduled exec time is : 2019-04-04 01:19:21
      Dancing happily!
      Add 1L water into the bucket!
      Add 1L water into the bucket!
      Add 1L water into the bucket!
      Scheduled exec time is : 2019-04-04 01:19:23
      Dancing happily!
      Add 1L water into the bucket!
      Add 1L water into the bucket!
      Scheduled exec time is : 2019-04-04 01:19:25
      Dancing happily!
      The number of canceled task in timer is : 0
      The waterRot has been aborted
      The number of canceled task in timer is : 1
      Current water is 5L

      5 Timer的缺陷

      天生的兩種缺陷

      • 管理并發(fā)任務(wù)的缺陷
        Timer有且僅有一個線程去執(zhí)行定時任務(wù),如果存在多個任務(wù),且任務(wù)時間過長,會導(dǎo)致執(zhí)行結(jié)果與預(yù)期不符。
        演示代碼:
      /*
       * ExTimer.java -- JDK 1.8
       */
      
      package timer;
      
      import java.util.Calendar;
      import java.util.Timer;
      import java.util.TimerTask;
      
      /**
       * Description:
       * <p>
       * <p>
       * @author ascribed
       * @date 2019-04-03 Wed PM 23:37:41
       */
      
      public class ConTimer {
          public static void main(String[] args) {
              Timer timer = new Timer();
              ConTimerTask exTimerTask1 = new ConTimerTask("No.1", 2000);
              ConTimerTask exTimerTask2 = new ConTimerTask("No.2", 2000);
              Calendar calendar = TimerUtils.current();
              TimerUtils.miscellaneous("Current time is : ", calendar
                      .getTime());
              timer.schedule(exTimerTask1, calendar.getTime());
              timer.schedule(exTimerTask2, calendar.getTime());
      //        timer.scheduleAtFixedRate(exTimerTask1, calendar.getTime(), 2000);
      //        timer.scheduleAtFixedRate(exTimerTask2, calendar.getTime(), 2000);
              
          }
      }
      
      class ConTimerTask extends TimerTask {
          private String name;
          private long costTime;
      
          public ConTimerTask(String name, long costTime) {
              this.setName(name);
              this.costTime = costTime;
          }
      
          @Override
          public void run() {
              System.out.println(name   "'s current exec time is : "   TimerUtils.sdf.format(Calendar.getInstance()
                      .getTime())); // 輸出當(dāng)前時間
              try {
                  Thread.sleep(costTime);
              } catch (InterruptedException e) {
                  e.printStackTrace();
              }
              System.out.println(name   "'s finish time is : "   TimerUtils.sdf.format(Calendar.getInstance()
                      .getTime())); // 輸出costTime之后的時間
          }
      
          public String getName() {
              return name;
          }
      
          public void setName(String name) {
              this.name = name;
          }
      
      }

      執(zhí)行結(jié)果:

      Current time is : 2019-04-04 01:04:24
      No.1's current exec time is : 2019-04-04 01:04:24
      No.1's finish time is : 2019-04-04 01:04:26
      No.2's current exec time is : 2019-04-04 01:04:26
      No.2's finish time is : 2019-04-04 01:04:28
      • 當(dāng)任務(wù)拋出異常時的缺陷
        如果TimerTask拋出RuntimeException,Timer會停止所有任務(wù)的運行。
        演示代碼:
      /*
       * ExTimer.java -- JDK 1.8
        */
      
      package timer;
      
      import java.util.Timer;
      import java.util.TimerTask;
      
      /**
       * Description:
       * <p>
       * <p>
       * @author ascribed
       * @date 2019-04-04 Thu AM 00:33:14
       */
      
      public class ExTimer {
          public static void main(String[] args) {
              Timer timer = new Timer();
              ExTimerTask task1 = new ExTimerTask("task1");
              ExTimerTask task2 = new ExTimerTask("task2");
              timer.scheduleAtFixedRate(task1, 1000, 1000);
              timer.scheduleAtFixedRate(task2, 1000, 2000 );
          }
      }
      class ExTimerTask extends TimerTask {
          private String name;
          
          public ExTimerTask(String name) {
              this.name = name;
          }
      
          @Override
          public void run() {
              System.out.println(name);
              throw new IllegalStateException();
          }
      
          public String getName() {
              return name;
          }
      
          public void setName(String name) {
              this.name = name;
          }
      }

      執(zhí)行結(jié)果:

      task1
      Exception in thread "Timer-0" java.lang.IllegalStateException
          at timer.ExTimerTask.run(ExTimer.java:37)
          at java.util.TimerThread.mainLoop(Timer.java:555)
          at java.util.TimerThread.run(Timer.java:505)
      • TimerTask是一次性
        定時器(Timer)的TimerTask實例只能schedule一次,再次調(diào)用會拋出運行時異常IllegalStateException,這是一個運行時異常。
        解決方法有二:一是反射修改state字段,二是每次用new一個TimerTask。

        Timer的使用禁區(qū)

      • 對時效性要求較高的多任務(wù)并發(fā)作業(yè)
      • 對復(fù)雜的任務(wù)的調(diào)度

        ?

      來源:https://www./content-4-655051.html

        本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
        轉(zhuǎn)藏 分享 獻花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多