2016-02-13 68 views
0

這是關於java的內置Timer類的。我需要一個方法在特定的時間間隔內被頻繁地調用,但是如果執行時間太長,我不希望它們堆積起來,所以解決方法是在所述方法的開始處排隊下一個執行。當然這意味着排隊發生在同一隊列中。這會解決還是會導致問題?從定時器線程調用java定時器任務

public class SomeClass extends TimerTask { 
    public static SomeClass timer; 
    public void run() { 
     timer.schedule(this,100); 
     //do stuff 
    } 

} 

回答

1

Java擁有執行程序服務來執行您想要執行的操作。看看方法ScheduledExecutorService#scheduleWithFixedDelay()。與方法ScheduledExecutorService#scheduleAtFixedRate()相反,具有固定延遲的方法不會跟上。

下面是一個例子:

public void run() { 
    Executors.newSingleThreadScheduledExecutor().scheduleWithFixedDelay(
      this::task, 0, 10, TimeUnit.MILLISECONDS); 
} 

public void task() { 
    // run your task 
} 

事實上,你的使用情況似乎不屬於標準庫的方法。但是,您應該可以使用以下課程來完成您想要的任務。

import java.util.concurrent.Executors; 
import java.util.concurrent.ScheduledExecutorService; 
import java.util.concurrent.TimeUnit; 
import java.util.function.Consumer; 

public class TimerExample { 
    private final ScheduledExecutorService executor = Executors 
      .newSingleThreadScheduledExecutor(); 
    private final Runnable task; 
    private final Consumer<Exception> onException; 
    private final long delay; 
    private final TimeUnit unit; 

    public TimerExample(Runnable task, Consumer<Exception> onException, 
      long delay, TimeUnit unit) { 
     this.task = task; 
     this.onException = onException; 
     this.delay = delay; 
     this.unit = unit; 
    } 

    public void start() { 
     executor.execute(this::execute); 
    } 

    private void execute() { 
     executor.schedule(this::execute, delay, unit); 
     try { 
      task.run(); 
     } catch (Exception e) { 
      onException.accept(e); 
     } 
    } 
} 

這裏的用法:

new TimerExample(() -> System.out.println("."), 
      Exception::printStackTrace, 20, TimeUnit.MILLISECONDS).start(); 

由於它採用單線程執行服務,它不會,直到前完成啓動下執行。另外,它在任務本身執行之前調度下一次執行。

另請參閱this SO-有關爲什麼您應該更喜歡Timer類上方的執行程序服務的問題。

你還得自己實現關機機制。

+0

儘管scheduleWithFixedRate()在上一次執行完成後才啓動下一次執行的計時器,但scheduleAtFixedRate()會聚集在一起。我搜索的是一種只聚集一次的方法,這樣,如果一次執行時間過長(比如說太長時間),下一次執行會立即開始,但是之後的執行會在指定的延遲後觸發,就像什麼都沒發生。 *示例:* 延遲:200 ms 執行[執行時間:10ms。開始:0ms] - >執行[花費:1000毫秒。開始:200ms] - >執行[花費:10毫秒。開始:1200ms] - >執行[花費:30ms。開始:1400ms] – Zain

+0

同時我自己寫了一堂課,如果有人想看看它應該是完全安全的:http://pastebin.com/raw/jcUrtwC5 :) 我的用例是一個實時模擬使用時間步。順便說一下,你正在使用C語法;) – Zain

+0

非常感謝你的回答,executor.schedule似乎能夠處理Timer類無法處理的事情,這兩個事情排隊了同樣的事情。我認爲? – Zain