2009-09-21 15 views
95

私はここで質問されたのと同様の質問を見つけましたが、私の満足感はありませんでした。だから質問をもう一度言い直してください。Timer&TimerTaskとJavaのスレッド+スリープ

私は、定期的に(例えば1分間隔で)行う必要がある作業があります。スリープで無限ループを持つ新しいスレッドを作成するのではなく、Timertask &タイマーを使用する利点は何ですか?

コードは、ロジックの実行がかかる場合timertask-

TimerTask uploadCheckerTimerTask = new TimerTask(){ 

public void run() { 
    NewUploadServer.getInstance().checkAndUploadFiles(); 
} 
}; 

Timer uploadCheckerTimer = new Timer(true); 
uploadCheckerTimer.scheduleAtFixedRate(uploadCheckerTimerTask, 0, 60 * 1000); 

コードは、スレッドとsleep-

Thread t = new Thread(){ 
public void run() { 
    while(true) { 
    NewUploadServer.getInstance().checkAndUploadFiles(); 
    Thread.sleep(60 * 1000); 
    } 
} 
}; 
t.start(); 

を使用してスニペット私は本当に私は一定のサイクルを欠場も心配する必要はありません使用してスニペットインターバル時間以上。

おかげで、
-Keshav

更新...これについてコメントしてください:
最近私が)のThread.sleep(対タイマーを使用しての間に別の違いを発見しました。現在のシステム時刻が午前11時であるとします。何らかの理由でシステム時刻を午前10時にロールバックした場合、Timerはタスクの実行が11:00 AMになるまでSTOPしますが、Thread.sleep()メソッドは妨げにならずにタスクの実行を継続します。これは、これら2つの間で何を使用するかを決定する主要な意思決定者になることができます。

+21

ポイント:TimerとTimerTaskは廃止され、効果的にExecutorServiceに置き換えられましたが、あなたのポイントはまだあります。 – skaffman

+0

ヒントをお寄せいただきありがとうございます。私はExecutorServiceを使用することにしました:) – Keshav

+0

ありがとうございました。 – Keshav

答えて

63

TimerTaskの利点は、あなたの意図をはるかに良く(コードの可読性)表現し、既にcancel()機能を実装していることです。

Timer uploadCheckerTimer = new Timer(true); 
uploadCheckerTimer.scheduleAtFixedRate(
    new TimerTask() { 
     public void run() { NewUploadServer.getInstance().checkAndUploadFiles(); } 
    }, 0, 60 * 1000); 
+0

タイマーがEverydayに使用されている場合、特定の2時間の午後9時と午前9時に、値を与える方法は?上のコードで... @ Zed? – gumuruh

11

タイマ/ TimerTaskをも考慮にあなたのタスクの実行時間を要するので、もう少し正確になります:それは短い形式だけでなく、あなた自身の例で書き込むことができることを

注意。そして、それはマルチスレッドの問題(デッドロックの回避など)をうまく処理します。もちろん、手作りのソリューションではなく、よくテストされた標準コードを使用する方が良いでしょう。

+0

それは非常に良い点です、ありがとうございます。 – Ridcully

3

Javaスレッドとsleepメソッドを使用してこのタスクを管理することには、重要な議論があります。 while(true)を使用してループ内に無期限に滞在し、スリープ状態にしてスレッドを休止します。 NewUploadServer.getInstance().checkAndUploadFiles();が同期したリソースを占有する場合はどうなりますか?他のスレッドはこれらのリソースにアクセスできないため、アプリケーション全体の処理速度を低下させる可能性のある飢餓状態が発生する可能性があります。このような種類のエラーは診断が難しく、その存在を防ぐことをお勧めします。

他のaproachは、その間にリソースを使用して、他のスレッドをさせながら、あなたのTimerTaskrun()メソッドを呼び出すことにより、すなわちNewUploadServer.getInstance().checkAndUploadFiles();、あなたに重要なコードの実行をトリガします。

+16

私はこの議論を理解していません。両方の選択肢がスレッドから同じメソッドを起動し、両方の選択肢がスレッドの実行を待つ間にスリープします。 2つの選択肢の間に飢餓の違いはありません。 – satur9nine

4

なぜ私が書いていたプログラムはタイマーを使用していましたが、ヒープサイズはスレッド/スリープの問題解決に変更した後は絶えず増加していました。

+6

Timerは、継続的に更新されるタスクのキューを作成します。タイマが完了すると、すぐにガベージコレクションされないことがあります。したがって、より多くのタイマーを作成すると、ヒープ上にオブジェクトが追加されるだけです。 Thread.sleep()はスレッドを一時停止するだけなので、メモリオーバーヘッドは非常に低くなります。 –

3

スレッドが例外をとり、強制終了されると、それが問題になります。 しかし、TimerTaskはそれを処理します。以前の実行での失敗に関係なく実行されます。

1

私はあなたの問題を理解していると思う、私は非常に似た何かを見ている。私は定期的なタイマーを持っています.30分ごとに、そして数日に2回です。私が読んだことと私が見るコメントから、すべてのタスクが決して完了しないので、ガベージコレクションは決して実行されないように見えます。私は、タイマーがスリープ状態になっているときにガベージコレクションが実行されると思うだろうが、私はそれを見ていないし、ドキュメンテーションによるとそうではない。

新しいスレッドの作成が完了し、ガベージコレクションが可能になると思います。

誰かが私が間違っていることを証明してください、私が継承したものを書き直すことは苦痛になるでしょう。

関連する問題