1。概要
主に2つのクラス、タイマーとティマタスクのクラスを使用して、Javaで定期的にタスクを実行する機能を実装します。タイマーは、指定されたプランに従って、指定されたタスクをバックグラウンドスレッドで実行するために使用されます。
Timertaskは抽象的なクラスであり、そのサブクラスはタイマーが計画できるタスクを表しています。実行される特定のコードは、Timertaskを実装する必要がある実行方法で記述されています。
2。最も簡単な例を見てみましょう
コードを通して説明しましょう
Import java.text.simpledateformat; Import java.util.date; import java.util.timer; import java.util.timertask; public class timerdemo {public static string getCurrentTime(){date date = new Date(); SimpleDateFormat sdf = new SimpledateFormat( "yyyy-mm-dd hh:mm:ss"); sdf.format(日付)を返します。 } public static void main(string [] args)throws arturnedexception {system.out.println( "main start:"+getCurrentTime()); starttimer(); thread.sleep(1000*5); // 5秒間system.out.println( "メインエンド:"+getCurrentTime()); } public static void starttimer(){timertask task = new timertask(){@override public void run(){system.out.println( "task run:"+getCurrentTime()); }};タイマータイマー= new Timer(); Timer.schedule(タスク、0); }}印刷による観測情報を容易にするために、メイン方法にいくつかの印刷情報を追加し、メインスレッドを睡眠にするためにsweet.sleepと呼ばれます。さらに、現在の日付を取得するために、getCurrentTimeメソッドがクラスに追加されます。
上記のコードでは、StartTimerメソッドでは、TimerTaskオブジェクト(タイマーによって実行されるタスク)が作成され、タイマーオブジェクトが作成され、タイマークラスのスケジュールメソッドが呼び出されます。タイマークラスには、異なるパラメーターを備えた複数のスケジュールメソッドがあります。ここで使用されているのは次のとおりです。
パブリックボイドスケジュール(Timertaskタスク、長い遅延)
この方法の意味は、タイマーが(ミリ秒)時間を遅らせた後にタスクタスクを実行することです。遅延が負または0の場合、タスクはすぐに実行されます。そして、それは1回限りの実行タスクであり、タスクはその後繰り返される(またはスケジュールされる)ことはありません。
タイマークラスの場合、次のように同じ関数を持つ方法も提供されます。
パブリックボイドスケジュール(Timertaskタスク、日付時刻)
この方法と上記の方法の違いは、上記の方法で、実行が一定期間遅延することを指定し、この方法では、実行が特定の時点で実行されることを指定します。システムの現在の時間がパラメーター時間で指定された時間を超えた場合、タスクはすぐに実行されることに注意してください。
上記のコードを実行すると、プログラムはすぐに次の2つの情報を印刷することがわかりました。
メインスタート:2016-01-13 22:23:18
タスクラン:2016-01-13 22:23:18
ここでスケジュールメソッドに渡す遅延パラメーター値は0であるため、タスクはすぐに実行されるため、2つのステートメントを印刷する時間は同じです。着信遅延値を自分で変更して、出力情報の変更を確認できます。約5秒後(つまり、スリープ時間)、私は1つのメッセージを印刷し続けました。
メインエンド:2016-01-13 22:23:23
情報を印刷する時間は、上記のステートメントの5秒不足であり、これは睡眠設定と一致しており、これも非常に合理的です。
しかし、私たちは非常に興味深い現象を見つけます、そして、私たちはプロセスが終了しないことがわかります。この時点で、メインのメインスレッドは終了しました。つまり、タイマーがタスクを完了した後、後で実行されるのを待っているタスクがない場合でも、タイマーで作成されたバックグラウンドスレッドはすぐに終了しません。関連するJavaドキュメントのドキュメントを確認し、タイマースレッドは積極的に終了せず、ガベージコレクションを待つ必要があると説明しましたが、Javaのガベージコレクションはコード自体では制御できませんが、仮想マシンによって制御されます。
調査後、タイマーオブジェクトを作成してタイマータイマー= new Timer()を実行するときに、ステートメント、タイマースレッドが作成されます。言い換えれば、上記のコードにTimer.schedule(task、0)がない場合でも。声明、プログラムは終了しません。これは非常に不合理だと思います。タイマークラスのソースコードを再度研究しましたが、ブールパラメーターを備えたコンストラクターもあることがわかりました。
パブリックタイマー(ブールイスダーモン)
パラメーター名からわかるように、パラメーター値がtrueの場合、タイマーによって作成されたタイマースレッドはデーモンスレッドです。デーモンスレッドの意味は、Javaプロセスのすべてのワーカースレッドが終了すると、デーモンスレッドが自動的に終了することです。
この時点で、上記の例でタイマーオブジェクトを作成するためのコードを変更するだけで、タイマー= new Timer(true);
プログラムが実行された後、プログラムはメインスレッド(メインスレッドはデーモンスレッドではなく、ワーカースレッド)の後に終了します。つまり、タイマースレッドも終了します。つまり、パラメーターを追加すると、作成されたデーモンスレッドはデーモンスレッドです。
しかし、問題は、実際のアプリケーションシナリオでは、多くのワーカースレッドが実行されており、プログラムがさりげなく終了しないことです。では、タイマーをすぐに終了または閉じることを望む場合はどうなりますか?これを以下に紹介します。
3。タイマーの出口
タイマークラスは、タイマーをキャンセルするキャンセル方法を提供します。キャンセルメソッドを呼び出すと、このタイマーが終了し、現在スケジュールされているすべてのタスクを破棄します。これは、現在実行中のタスクを妨害しません(存在する場合)。タイマーが終了すると、その実行スレッドも終了し、それ以上のタスクをスケジュールすることはできません。
このタイマーと呼ばれるタイマータスクの実行方法内でこのメソッドを呼び出すことにより、実行されるタスクがこのタイマーによって実行される最後のタスクであることを絶対に確認できることに注意してください。この方法は繰り返し呼ぶことができます。ただし、2番目と後続の呼び出しは無効です。
別の例コードを見てみましょう:
Import java.text.simpledateformat; Import java.util.date; import java.util.timer; import java.util.timertask; public class timerdemo {public static string getCurrentTime(){date date = new Date(); SimpleDateFormat sdf = new SimpledateFormat( "yyyy-mm-dd hh:mm:ss"); sdf.format(日付)を返します。 } public static void main(string [] args)throws arturnedexception {system.out.println( "main start:"+getCurrentTime());タイマータイマー= starttimer(); thread.sleep(1000*5); // 5秒間system.out.println( "メインエンド:"+getCurrentTime()); Timer.Cancel(); } public static Timer starttimer(){timertask task = new timertask(){@Override public void run(){system.out.println( "task run:"+getCurrentTime()); }};タイマータイマー= new Timer(); Timer.schedule(タスク、0);リターンタイマー; }}プログラムの実行は、上記の例の出力とまったく同じです。違いは、メインメソッドが終了したときです。このプロセスは積極的に終了します。つまり、タイマースレッドが閉じられています。
メインメソッドのキャンセルメソッドを呼び出すためです。 Timertaskの実行方法でキャンセルメソッドを呼び出していない場合は、実行するタスクが開始または完了したことを確認してください。キャンセルを呼び出すだけで、すべてのタスクは実行されません。たとえば、上記のコード、
たとえば、上記のコードでは、メインメソッドのキャンセルメソッドを呼び出さない場合は、Timer.schedule(task、0)を追加します。 starttimerメソッドのステートメントとtimer.cancel()を追加します。実行後のステートメントは、実行が完了する前にキャンセルされるため、タイマータスクは実行されないことがわかります。
4.タスクを定期的に実行します
上記の例では、1回限りのタスクを紹介しています。つまり、タイマー時間が来ました。タスクが実行された後、後で繰り返されません。実際のアプリケーションでは、同じタスクを定期的に繰り返し実行する必要がある多くのシナリオがあります。 2つの状況があります。1つは時々タスクを実行することであり、もう1つは毎日(または毎週、毎月、毎月)、特定の(または複数の)時点でタスクを実行することです。
まず、最初のケースを見てみましょう。これは、10秒ごとに同じタスクを実行する例です。コードは次のとおりです。
Import java.text.simpledateformat; Import java.util.date; import java.util.timer; import java.util.timertask; public class timerdemo {public static string getCurrentTime(){date date = new Date(); SimpleDateFormat sdf = new SimpledateFormat( "yyyy-mm-dd hh:mm:ss"); sdf.format(日付)を返します。 } public static void main(string [] args)throws arturnedexception {system.out.println( "main start:"+getCurrentTime()); starttimer(); } public static void starttimer(){timertask task = new timertask(){@override public void run(){system.out.println( "task run:"+getCurrentTime()); {thread.sleep(1000*3); } catch(arturnedexception e){e.printstacktrace(); }}};タイマータイマー= new Timer(); Timer.schedule(タスク、1000*5,1000*10); }}上記のプログラムを実行すると、出力情報が次のとおりです(タイマーが停止せず、タスクが繰り返されるため、出力は継続的に出力されます。以前の出力の一部のみがここにコピーされます)
メインスタート:2016-01-14 08:41:14
タスクラン:2016-01-14 08:41:19
タスクラン:2016-01-14 08:41:29
タスクラン:2016-01-14 08:41:39
タスクラン:2016-01-14 08:41:49
タスクの実行:2016-01-14 08:42:00
タスクラン:2016-01-14 08:42:10
タスクラン:2016-01-14 08:42:20
タスクラン:2016-01-14 08:42:30
タスクラン:2016-01-14 08:42:40
上記のコードでは、Timer.schedule(タスク、1000*5,1000*10)を呼び出します。これは、タスクが5秒遅れ、10秒ごとに繰り返されることを意味します。出力情報の印刷時間は予想と同じであることがわかります。さらに、間隔はタスク開始時間に基づいて計算されることがわかります。つまり、タスクが完了してからさらに10秒待つことはありません。
タイマークラスには、次のようにこのような機能を実装する2つの方法があります。
パブリックボイドスケジュール(Timertaskタスク、長い遅延、長期間)パブリックボイドスケジュール(Timertaskタスク、初めて、長期間)
上記のコードを使用する最初の方法。 2つの方法の違いは、最初の実行の時間です。最初の方法は、特定の期間(ミリ秒)の指定された遅延の後に実行されます。 2番目の方法は、指定された時点で実行されます。
現時点では、次のシナリオを検討します。タスクの実行時間が次の待ち時間を超えた場合、何が起こりますか?コードを通してそれを見てみましょう:
Import java.text.simpledateformat; Import java.util.date; import java.util.timer; import java.util.timertask; public class timerdemo {public static string getCurrentTime(){date date = new Date(); SimpleDateFormat sdf = new SimpledateFormat( "yyyy-mm-dd hh:mm:ss"); sdf.format(日付)を返します。 } public static void main(string [] args)throws arturnedexception {system.out.println( "main start:"+getCurrentTime()); starttimer(); } public static void starttimer(){timertask task = new timertask(){@override public void run(){system.out.println( "task begin:"+getCurrentTime()); {thread.sleep(1000*10); } catch(arturnedexception e){e.printstacktrace(); } system.out.println( "タスクエンド:"+getCurrentTime()); }};タイマータイマー= new Timer(); Timer.schedule(タスク、1000*5,1000*5); }}前のコードと比較して、2つのコードのみを変更し、印刷を変更しました。 1つは、実行方法の睡眠を10秒に変更することであり、もう1つはタスクの実行サイクルを5秒に変更することです。言い換えれば、タスクの実行時間は、タスクの繰り返し実行間の間隔を超えています。プログラムを実行すると、以前の出力は次のとおりです。
メインスタート:2016-01-14 09:03:51
タスクの開始:2016-01-14 09:03:56
タスクエンド:2016-01-14 09:04:06
タスクの開始:2016-01-14 09:04:06
タスクエンド:2016-01-14 09:04:16
タスクの開始:2016-01-14 09:04:16
タスクエンド:2016-01-14 09:04:26
タスクの開始:2016-01-14 09:04:26
タスクエンド:2016-01-14 09:04:36
タスクの開始:2016-01-14 09:04:36
タスクエンド:2016-01-14 09:04:46
タスクの開始:2016-01-14 09:04:46
タスクエンド:2016-01-14 09:04:56
各タスクが実行された後、次のタスクがすぐに実行されることがわかります。タスクの開始からタスクの完了までの時間がタスクの繰り返しの間の間隔を超えたため、実行は繰り返されます。
5。タスクを定期的に実行します(固定時点を繰り返します)
このような関数を実装し、毎日午前1時に定期的にタスクを実行しましょう。この機能は、このタスクのデータバックアップやデータ統計などの時間のかかるタスクの完成やリソースを消費するタスクの完了など、多くのシステムでこの機能を備えています。コードは次のとおりです。
java.text.simpledateformat; Import java.util.calendar; Import java.util.date; Import java.util.timer; Import java.util.timertask; public class timerdemo {public static String getCurrentTime(){日付=新しい日付= new(); SimpleDateFormat sdf = new SimpledateFormat( "yyyy-mm-dd hh:mm:ss"); sdf.format(日付)を返します。 } public static void main(string [] args)throws arturnedexception {system.out.println( "main start:" + getCurrentTime()); starttimer(); } public static void starttimer(){timertask task = new timertask(){@override public void run(){system.out.println( "task begin:" + getCurrentTime()); {thread.sleep(1000 * 20); } catch(arturnedexception e){e.printstacktrace(); } system.out.println( "タスクエンド:" + getCurrentTime()); }};タイマータイマー= new Timer(); Timer.schedule(task、buildtime()、1000 * 60 * 60 * 24); } private static date buildtime(){calendary calendar = calendar.getInstance(); calendar.set(calendar.hour_of_day、1); calendar.set(calendar.minute、0); calendar.set(Callearn.second、0); date time = calendar.getTime(); if(time.before(new date())){//現在の時間が午前1時以降である場合、1日が必要である場合、タスクはすぐに実行されます。 //多くのシステムは、システムが起動するときにすぐにタスクを実行する必要があることがよくありますが、毎日午前1時に実行する必要があります。どうすればいいですか? //非常に単純です。システムが呼び出しを初期化したときにタスクを個別に実行するだけです(タイマーが必要ありません。そのタスクを実行するのはコードだけです)time = addday(time、1); }戻り時間; } private static date addday(date date、int days){calendar startdt = calendar.getInstance(); startdt.settime(date); startdt.add(calendar.day_of_month、days); return startdt.getTime(); }}24時間の間隔で実行されるため、出力の観察を待つことは不可能です。
6。概要
この記事では、Javaタイマークラスを使用して時限タスクを実行する方法のメカニズムを紹介します。まだ注意を払う方法はまだたくさんあることがわかります。この記事で紹介した例では、各タイマーは1つのタスクのみに対応しています。
この記事で導入されたコンテンツは、ほとんどのアプリケーションシナリオを満たすことができますが、タイマーの複数のタスクを含めるなど、まだいくつかの問題がありますか?タイマーがキャンセルされた後、もう一度タスクを追加できますか?タイマークラスで利用可能な他の方法は何ですか?これらの質問は、次のブログ投稿で紹介されます。
元のリンク:http://www.cnblogs.com/51kata/p/5128745.html
上記はこの記事のすべての内容です。みんなの学習に役立つことを願っています。誰もがwulin.comをもっとサポートすることを願っています。