2015-08-18 62 views
0

scheduleAtFixedRate這樣的工作是如何工作的?它在幕後如何工作,使用它有什麼懲罰?幕後的Java ScheduledExecutorService

更具體地說,我有一個任務,我想定期運行,比如說每12小時。這段時間並不嚴格,所以我的第一本能是檢查每個請求(tomcat服務器),如果它已經超過了上次執行任務的12個小時以上,並且如果是,執行它並重置定時器。其缺點是我必須對每個請求進行一次小小的檢查,確保任務只運行一次(使用信號量或類似的東西),並且如果沒有請求,任務可能無法在很長時間內執行。

scheduleAtFixedRate可以更容易地安排一個循環任務,但由於我不知道它是如何實現的,我不知道性能的影響是什麼。是否有線程不斷檢查任務是否由於運行?等

編輯:Timer.java,有一個mainLoop函數,在我的理解,是這樣的(過於簡化):

while(true) { 
    currentTime = System.currentTimeMillis(); 
    if(myTask.nextExecutionTime == currentTime) myTask.run(); 
} 

這會不會循環嘗試跑得快儘可能使用一噸CPU(我知道,顯然不是,但爲什麼)?在那裏沒有Thread.sleep來減慢速度。

+1

使用像[quartz-scheduler](http://quartz-scheduler.org/)或類似的庫。或者使用'ScheduledExecutorService'滾動你自己的。 –

+1

「因爲我不知道它是怎麼做的」查看源代碼,也許? –

回答

1

如果你想弄清楚它是如何工作的,你可以閱讀代碼。

在CPU和內存方面,使用ScheduledExecutorService會有一些開銷,但是在小時,分鐘,秒甚至毫秒的範圍內,它可能無需擔心。如果你的任務在微秒範圍內運行,我會考慮更輕的重量。

總之,開銷可能太小,你不會注意到。它給你帶來的好處是易用性,而且很可能是值得的。

+0

另一個需要注意的是jdk的ScheduledThreadPoolExecutor實現使用同步隊列。因此,雖然它使一個體面的*調度程序*因爲在提交任務時鎖定爭用而將其用作雙重角色*執行程序將是一個可怕的想法。 – the8472

+0

@ the8472你必須以很高的速度提交任務。如果你每小時有一個,它不會。 –

+0

如果你做UDP網絡連接並提交超時例如這可能很重要。此外,重複的任務必須重新提交自己,因此,即使只提交一次,如果您有多個任務在多個線程上彈出或關閉工作隊列,仍然可以與鎖進行競爭。最後但並非最不重要的一點是,STPE也是一個普通的線程池,如果它被用作('execute()'/'submit()'),你也會產生這種開銷。 – the8472

相關問題