程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> 詳解java准時義務

詳解java准時義務

編輯:關於JAVA

詳解java准時義務。本站提示廣大學習愛好者:(詳解java准時義務)文章只能為提供參考,不一定能成為您想要的結果。以下是詳解java准時義務正文


 在我們編程進程中假如須要履行一些簡略的准時義務,不必做龐雜的掌握,我們可以斟酌應用JDK中的Timer准時義務來完成。上面LZ就其道理、實例和Timer缺點三個方面來解析java Timer准時器。

1、簡介
      在java中一個完全准時義務須要由Timer、TimerTask兩個類來合營完成。 API中是如許界說他們的,Timer:一種對象,線程用其支配今後在後台線程中履行的義務。可支配義務履行一次,或許按期反復履行。由TimerTask:Timer 支配為一次履行或反復履行的義務。我們可以如許懂得Timer是一種准時器對象,用來在一個後台線程籌劃履行指定義務,而TimerTask一個籠統類,它的子類代表一個可以被Timer籌劃的義務。
Timer類
      在對象類Timer中,供給了四個結構辦法,每一個結構辦法都啟動了計時器線程,同時Timer類可以包管多個線程可以同享單個Timer對象而無需停止內部同步,所以Timer類是線程平安的。然則因為每個Timer對象對應的是單個後台線程,用於次序履行一切的計時器義務,普通情形下我們的線程義務履行所消費的時光應當異常短,然則因為特別情形招致某個准時器義務履行的時光太長,那末他就會“獨有”計時器的義務履行線程,厥後的一切線程都必需期待它履行完,這就會延遲後續義務的履行,使這些義務聚積在一路,詳細情形我們前面剖析。
      當法式初始化完成Timer後,准時義務就會依照我們設定的時光去履行,Timer供給了schedule辦法,該辦法有多中重載方法來順應分歧的情形,以下:
      schedule(TimerTask task, Date time):支配在指定的時光履行指定的義務。
      schedule(TimerTask task, Date firstTime, long period) :支配指定的義務在指定的時光開端停止反復的固定延遲履行。
      schedule(TimerTask task, long delay) :支配在指定延遲後履行指定的義務。
      schedule(TimerTask task, long delay, long period) :支配指定的義務從指定的延遲後開端停止反復的固定延遲履行。
      同時也重載了scheduleAtFixedRate辦法,scheduleAtFixedRate辦法與schedule雷同,只不外他們的著重點分歧,差別前面剖析。
      scheduleAtFixedRate(TimerTask task, Date firstTime, long period):支配指定的義務在指定的時光開端停止反復的固定速度履行。
      scheduleAtFixedRate(TimerTask task, long delay, long period):支配指定的義務在指定的延遲後開端停止反復的固定速度履行。
TimerTask
      TimerTask類是一個籠統類,由Timer 支配為一次履行或反復履行的義務。它有一個籠統辦法run()辦法,該辦法用於履行響應計時器義務要履行的操作。是以每個詳細的義務類都必需繼續TimerTask,然後重寫run()辦法。
      別的它還有兩個非籠統的辦法:
      boolean cancel():撤消此計時器義務。
      long scheduledExecutionTime():前往此義務比來現實履行的支配履行時光。

2、實例
2.1、指定延遲時光履行准時義務

public class TimerTest01 { 
  Timer timer; 
  public TimerTest01(int time){ 
    timer = new Timer(); 
    timer.schedule(new TimerTaskTest01(), time * 1000); 
  } 
   
  public static void main(String[] args) { 
    System.out.println("timer begin...."); 
    new TimerTest01(3); 
  } 
} 
 
public class TimerTaskTest01 extends TimerTask{ 
 
  public void run() { 
    System.out.println("Time's up!!!!"); 
  } 
} 

運轉成果:
起首打印:timer begin.... 
 
3秒後打印:Time's up!!!! 

2.2、在指准時間履行准時義務

public class TimerTest02 { 
  Timer timer; 
   
  public TimerTest02(){ 
    Date time = getTime(); 
    System.out.println("指准時間time=" + time); 
    timer = new Timer(); 
    timer.schedule(new TimerTaskTest02(), time); 
  } 
   
  public Date getTime(){ 
    Calendar calendar = Calendar.getInstance(); 
    calendar.set(Calendar.HOUR_OF_DAY, 11); 
    calendar.set(Calendar.MINUTE, 39); 
    calendar.set(Calendar.SECOND, 00); 
    Date time = calendar.getTime(); 
     
    return time; 
  } 
   
  public static void main(String[] args) { 
    new TimerTest02(); 
  } 
} 
 
public class TimerTaskTest02 extends TimerTask{ 
 
  @Override 
  public void run() { 
    System.out.println("指准時間履行線程義務..."); 
  } 
} 

      其時間達到11:39:00時就會履行該線程義務,固然年夜於該時光也會履行!!履行成果為:
指准時間time=Tue Jun 10 11:39:00 CST 2014 
指准時間履行線程義務...  
2.3、在延遲指准時間後以指定的距離時光輪回履行准時義務

public class TimerTest03 { 
  Timer timer; 
   
  public TimerTest03(){ 
    timer = new Timer(); 
    timer.schedule(new TimerTaskTest03(), 1000, 2000); 
  } 
   
  public static void main(String[] args) { 
    new TimerTest03(); 
  } 
} 
 
public class TimerTaskTest03 extends TimerTask{ 
 
  @Override 
  public void run() { 
    Date date = new Date(this.scheduledExecutionTime()); 
    System.out.println("本次履行該線程的時光為:" + date); 
  } 
} 

運轉成果:
本次履行該線程的時光為:Tue Jun 10 21:19:47 CST 2014 
本次履行該線程的時光為:Tue Jun 10 21:19:49 CST 2014 
本次履行該線程的時光為:Tue Jun 10 21:19:51 CST 2014 
本次履行該線程的時光為:Tue Jun 10 21:19:53 CST 2014 
本次履行該線程的時光為:Tue Jun 10 21:19:55 CST 2014 
本次履行該線程的時光為:Tue Jun 10 21:19:57 CST 2014 
.................  
      關於這個線程義務,假如我們不將該義務停滯,他會一向運轉下去。
      關於下面三個實例,LZ只是簡略的演示了一下,同時也沒有講授scheduleAtFixedRate辦法的例子,其實該辦法與schedule辦法一樣!
2.4、剖析schedule和scheduleAtFixedRate
      1)、schedule(TimerTask task, Date time)、schedule(TimerTask task, long delay)
      關於這兩個辦法而言,假如指定的籌劃履行時光scheduledExecutionTime<= systemCurrentTime,則task會被立刻履行。scheduledExecutionTime不會由於某一個task的過度履行而轉變。
      2)、schedule(TimerTask task, Date firstTime, long period)、schedule(TimerTask task, long delay, long period)
      這兩個辦法與下面兩個就有點兒分歧的,後面提過Timer的計時器義務會由於前一個義務履行時光較長而延時。在這兩個辦法中,每次履行的task的籌劃時光會跟著前一個task的現實時光而產生轉變,也就是scheduledExecutionTime(n+1)=realExecutionTime(n)+periodTime。也就是說假如第n個task因為某種情形招致此次的履行時光進程,最初招致systemCurrentTime>= scheduledExecutionTime(n+1),這是第n+1個task其實不會由於到時了而履行,他會期待第n個task履行完以後再履行,那末如許必將會招致n+2個的履行完成scheduledExecutionTime放生轉變即scheduledExecutionTime(n+2) = realExecutionTime(n+1)+periodTime。所以這兩個辦法加倍重視保留距離時光的穩固。
      3)、scheduleAtFixedRate(TimerTask task, Date firstTime, long period)、scheduleAtFixedRate(TimerTask task, long delay, long period)
      在後面也提過scheduleAtFixedRate與schedule辦法的著重點分歧,schedule辦法著重保留距離時光的穩固,而scheduleAtFixedRate辦法加倍著重於堅持履行頻率的穩固。為何這麼說,緣由以下。在schedule辦法中會由於前一個義務的延遲而招致厥後面的准時義務延時,而scheduleAtFixedRate辦法則不會,假如第n個task履行時光太長招致systemCurrentTime>= scheduledExecutionTime(n+1),則不會做任多麼待他會立刻履行第n+1個task,所以scheduleAtFixedRate辦法履行時光的盤算辦法分歧於schedule,而是scheduledExecutionTime(n)=firstExecuteTime +n*periodTime,該盤算辦法永久堅持不變。所以scheduleAtFixedRate加倍著重於堅持履行頻率的穩固。

3、Timer的缺點
3.1、Timer的缺點
      Timer計時器可以准時(指准時間履行義務)、延遲(延遲5秒履行義務)、周期性地履行義務(每隔個1秒履行義務),然則,Timer存在一些缺點。起首Timer對換度的支撐是基於相對時光的,而不是絕對時光,所以它對體系時光的轉變異常敏感。其次Timer線程是不會捕捉異常的,假如TimerTask拋出的了未檢討異常則會招致Timer線程終止,同時Timer也不會從新恢單線程的履行,他會毛病的以為全部Timer線程都邑撤消。同時,曾經被支配單還沒有履行的TimerTask也不會再履行了,新的義務也不克不及被調劑。故假如TimerTask拋出未檢討的異常,Timer將會發生沒法預感的行動。
1)、Timer治理時光延遲缺點
      後面Timer在履行准時義務時只會創立一個線程義務,假如存在多個線程,若個中某個線程由於某種緣由而招致線程義務履行時光太長,跨越了兩個義務的距離時光,會產生一些缺點:

public class TimerTest04 { 
  private Timer timer; 
  public long start;   
   
  public TimerTest04(){ 
    this.timer = new Timer(); 
    start = System.currentTimeMillis(); 
  } 
   
  public void timerOne(){ 
    timer.schedule(new TimerTask() { 
      public void run() { 
        System.out.println("timerOne invoked ,the time:" + (System.currentTimeMillis() - start)); 
        try { 
          Thread.sleep(4000);  //線程休眠3000 
        } catch (InterruptedException e) { 
          e.printStackTrace(); 
        } 
      } 
    }, 1000); 
  } 
   
  public void timerTwo(){ 
    timer.schedule(new TimerTask() { 
      public void run() { 
        System.out.println("timerOne invoked ,the time:" + (System.currentTimeMillis() - start)); 
      } 
    }, 3000); 
  } 
   
  public static void main(String[] args) throws Exception { 
    TimerTest04 test = new TimerTest04(); 
     
    test.timerOne(); 
    test.timerTwo(); 
  } 
} 

依照我們正常思緒,timerTwo應當是在3s後履行,其成果應當是:
timerOne invoked ,the time:1001 
timerOne invoked ,the time:3001 
然則適得其反,timerOne因為sleep(4000),休眠了4S,同時Timer外部是一個線程,招致timeOne所需的時光跨越了距離時光,成果:
timerOne invoked ,the time:1000 
timerOne invoked ,the time:5000 
2)、Timer拋出異常缺點
假如TimerTask拋出RuntimeException,Timer會終止一切義務的運轉。以下:

public class TimerTest04 { 
  private Timer timer; 
   
  public TimerTest04(){ 
    this.timer = new Timer(); 
  } 
   
  public void timerOne(){ 
    timer.schedule(new TimerTask() { 
      public void run() { 
        throw new RuntimeException(); 
      } 
    }, 1000); 
  } 
   
  public void timerTwo(){ 
    timer.schedule(new TimerTask() { 
       
      public void run() { 
        System.out.println("我會不會履行呢??"); 
      } 
    }, 1000); 
  } 
   
  public static void main(String[] args) { 
    TimerTest04 test = new TimerTest04(); 
    test.timerOne(); 
    test.timerTwo(); 
  } 
} 

運轉成果:timerOne拋出異常,招致timerTwo義務終止。

Exception in thread "Timer-0" java.lang.RuntimeException 
  at com.chenssy.timer.TimerTest04$1.run(TimerTest04.java:25) 
  at java.util.TimerThread.mainLoop(Timer.java:555) 
  at java.util.TimerThread.run(Timer.java:505) 

      關於Timer的缺點,我們可以斟酌 ScheduledThreadPoolExecutor 來替換。Timer是基於相對時光的,對體系時光比擬敏感,而ScheduledThreadPoolExecutor 則是基於絕對時光;Timer是外部是單一線程,而ScheduledThreadPoolExecutor外部是個線程池,所以可以支撐多個義務並發履行。
3.2、用ScheduledExecutorService替換Timer
1)、處理成績一:

public class ScheduledExecutorTest { 
  private ScheduledExecutorService scheduExec; 
   
  public long start; 
   
  ScheduledExecutorTest(){ 
    this.scheduExec = Executors.newScheduledThreadPool(2);  
    this.start = System.currentTimeMillis(); 
  } 
   
  public void timerOne(){ 
    scheduExec.schedule(new Runnable() { 
      public void run() { 
        System.out.println("timerOne,the time:" + (System.currentTimeMillis() - start)); 
        try { 
          Thread.sleep(4000); 
        } catch (InterruptedException e) { 
          e.printStackTrace(); 
        } 
      } 
    },1000,TimeUnit.MILLISECONDS); 
  } 
   
  public void timerTwo(){ 
    scheduExec.schedule(new Runnable() { 
      public void run() { 
        System.out.println("timerTwo,the time:" + (System.currentTimeMillis() - start)); 
      } 
    },2000,TimeUnit.MILLISECONDS); 
  } 
   
  public static void main(String[] args) { 
    ScheduledExecutorTest test = new ScheduledExecutorTest(); 
    test.timerOne(); 
    test.timerTwo(); 
  } 
} 

運轉成果:
timerOne,the time:1003 
timerTwo,the time:2005 
2)、處理成績二

public class ScheduledExecutorTest { 
  private ScheduledExecutorService scheduExec; 
   
  public long start; 
   
  ScheduledExecutorTest(){ 
    this.scheduExec = Executors.newScheduledThreadPool(2);  
    this.start = System.currentTimeMillis(); 
  } 
   
  public void timerOne(){ 
    scheduExec.schedule(new Runnable() { 
      public void run() { 
        throw new RuntimeException(); 
      } 
    },1000,TimeUnit.MILLISECONDS); 
  } 
   
  public void timerTwo(){ 
    scheduExec.scheduleAtFixedRate(new Runnable() { 
      public void run() { 
        System.out.println("timerTwo invoked ....."); 
      } 
    },2000,500,TimeUnit.MILLISECONDS); 
  } 
   
  public static void main(String[] args) { 
    ScheduledExecutorTest test = new ScheduledExecutorTest(); 
    test.timerOne(); 
    test.timerTwo(); 
  } 
} 

運轉成果:

timerTwo invoked ..... 
timerTwo invoked ..... 
timerTwo invoked ..... 
timerTwo invoked ..... 
timerTwo invoked ..... 
timerTwo invoked ..... 
timerTwo invoked ..... 
timerTwo invoked ..... 
timerTwo invoked ..... 
........................ 

以上就是本文的全體內容,關於java准時義務就為年夜家引見到這,願望對年夜家的進修有所贊助。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved