2010-07-19 77 views
0

我使用Timer作爲進程中斷機制。邏輯的流程如下:使用Timer和TimerTask時的Java線程執行順序

T0:在T0創建新的計時器,並安排一個新的計時器任務在T2來執行(1個第二任務延遲,任務是非常簡單 - 設置一個標誌變量)

T1 :在主調用線程,睡5秒

T2:在計時器線程,任務執行

T5:睡眠完成

T6:取消計時器和任何計劃任務

該代碼在我的Windows和Ubuntu開發環境中完美工作。但是,當我在我的SLES運行相同的代碼10的構建服務器,日誌記錄表示該執行順序:

T0:定時器和定時器任務被創建在T2執行

T1:主線程休眠5秒

T5:主線程醒來

T6:定時器取消

T7:執行任務

誰能報價爲什麼會出現這種情況的解釋?非常感謝。

+0

你正在使用什麼記錄機制?這可能只是說日誌沒有被正確刷新。 – Tom 2010-07-19 20:09:49

+0

我正在使用log4j。我爲每個步驟使用System.currentTimeMillis記錄時間戳,所以我希望記錄輸出的順序不是罪魁禍首。 – Chrom 2010-07-19 20:13:57

回答

0

嗯。我很驚訝,你看到了很大的差異(以秒爲單位?),但我想你可能會看到不同的機器到機器執行順序,jvm到jvm等等。特別是,當JIT編譯你的代碼第一次,我傾向於在代碼中看到延遲(與後續執行相同的代碼相比),大小爲100-300ms,所以在代碼中可能更具戲劇性?

不確定你的意思是「過程中斷機制」。你的意思是計時器任務中斷某個線程?

無論如何,我現在可以建議的是使用System.nanoTime()來代替。 (儘管我不認爲它會解釋任何事情,但在嚴肅的測量中不鼓勵使用System.currentTimeMillis())。一般建議在您的JAVA_OPTS中添加-server,這樣您可以在JIT優化代碼時看到行爲。多次運行您的代碼並進行統計也是非常明智的。

如果我是你,我會先做這些小事情,然後使用CyclicBarrier,CountdownLatch等同步器進行調試,並查看延遲到底在哪裏。

什麼是SLES中的「背景噪音」(活動度)?也許操作系統非常非常忙碌或什麼?

該任務的性質是什麼?它與網絡/ IO有關嗎?

0

原來這是一個時間戳問題。使用新的Date().getTime代替System.currentTimeMillis產生了執行時間戳的預期順序。

感謝所有的好主意。

0

您應該考慮在任務完成時觸發一個事件。這確保了執行順序。