開発では、数分ごとに特定の操作を実行するなど、いくつかの定期的な操作が必要になることがよくあります。この時点で、タイマーを設定する必要があります。 Javaで実装する最も便利で効率的な方法は、java.util.timerツールクラスを使用して、java.util.timertaskタスクをスケジュールすることです。
タイマーは、背景スレッドで実行されるタスクを後でアレンジするために使用するツールです。タスクは一度実行することも、繰り返し実行することもできます。実際には、タイミングのスケジューリングが所有するティマタスクをスケジュールするスレッドです。
Timertaskは、サブクラスがタイマーによって実行または繰り返されるタスクとして配置されている抽象クラスです。実際、それは実行方法を備えたクラスであり、定期的に実行する必要があるコードは実行方法本体に配置されます。
JavaはJDK1.3でタイマークラスタイマーを起動し、DouleaはJDK1.5の後のマルチスレッドをサポートするScheduleThreadPoolexecutorを新たに開発しました。後者のパフォーマンスから判断すると、タイマーを完全に交換することを検討できます。
タイマーとScheduleThreadPoolexecutorの比較:
1.タイマーはJDK1.3から始まります。その原則は、TimerTaskアレイをキューとして使用して、このキューにすべてのタイミングタスクを追加することです。次に、スレッドを開始します。キューが空の場合、スレッドはブロックされます。キューにデータがある場合、スレッドはティマタスクを削除して判断します
時間が最新かどうかにかかわらず、実行時間が現在の時間以下である場合、タスクは実行を開始します。単一のスレッドの性質により、いくつかの問題が発生します(詳細なコードは後でです):
まず、タイマーに追加するタスクが時間がかかる場合、このタイマーはタイマータスクを単一のスレッドシーケンシャルな方法で実行するため、後続のタスクのタイムリーな実行に影響します。
Javaコード
//問題の例:m_timer.scheduleatfixedrate(new taskuselongtime()、1000、5000); m_timer.scheduleatfixedrate(new tasknormal()、5000、3000);ランニング結果:14:44:29:タイマーが10秒間眠っています14:44:49:実行されたタスクの実行
第二に、タイマー内のスレッドはターゲーションエクセプトの例外のみをキャッチするため、カスタムタイミングタスクが可能な例外をキャッチせず、例外をスローする場合、
//例2:m_timer.schedule(new TaskThrowexception()、1000); m_timer.schedule(new tasknormal()、2000);実行結果:14:47:37:スレッド「タイマー-0」java.lang.runtimeexception at timer_test.timertest $ taskthrowexception.run(timertest.java:85)のスレッドで例外をスローします。 java.util.timerthread.run(timer.java:462)結果分析:例外がタスクによってスローされた後、その後のtasnormalタスクは実行され続けることはできません。
これにより、タイマースレッドが停止し、他の後続のタスクを実行できなくなります。
第三に、同時に発生する複数のタイミングタスクを処理できません
// 3つの質問の分析:m_timer.scheduleatfixedrate(new taskuselongtime( "Timer1")、1000、15000); m_timer.scheduleatfixedrate(new taskuselongtime( "Timer2")、1000、15000);ランニング結果:14:50:16:Timer1は10秒間眠っています
コード例:
パッケージTimer_test; Import Java.text.simpledateformat; Import Java.util.date; Import Java.util.timer; Import java.util.timertask; public final timertest {private final timer m_timer = new Timer(); public static void(){new voids() {//問題のサンプル:m_timer.scheduleatfixedrate(new taskuselongtime()、1000、5000); m_timer.scheduleatfixedrate(new tasknormal()、5000、3000); //例2:// m_timer.schrowexcection(新しいtaskthrowexcection(1000); // m_timer.schedule(new Tasknormal()、2000); //例3:// m_timer.scheduleatfixedrate(new taskuselongtime( "Timer1")、1000、5000); // m_timer.scheduleatfixedrate(new taskuselongtime( "timer2")、1000、5000);} private class taskuselongtime extends timertask {timer "; public taskuselongtime(){} public task name(} publickname; run(){try {system.out.println(getCurrenttime()+":"+m_taskname+"は10秒眠っています"); sweep(10000);} catch(arternedexception e){}}} private class tasknormal extends timertask {@override public void run()通常の実行 ");}}プライベートクラスのタスクストローエクセプトエクステントティマタスク{@Override public void run(){system.out.println(getCurrentTime()+"+":スロー例外");スローnew runtimeexception();}} private string getCurrentTime() 日付());}}2.ScheduleThreadPoolexecutor
ScheduleThreadPoolexecutorはJDK1.5で開始され、Doulea氏によって書かれました。 ThreadPoolexecutorとDelayQueueの巧妙な組み合わせを使用して、マルチスレッドタイマーの実装を完了し、タイマーの単一スレッドによって引き起こされる上記の3つの欠陥を解決します。
問題1の問題は、単一のスレッドが順次実行されるため、後続のタスクを期限内に完了できないことです。マルチスレッドはこの問題を簡単に解決できることがわかります。同時に、TaskUselongtimeの実行時間が10秒であることに気付きました(後続のコードを参照してください)。タスク間隔は5秒のタイミングを計りましたが、結果から、タスクの実行間隔が10秒であることがわかりました。そのため、スケジュールreadedpoolexecutorがタスクあたりのタスクごとに動作することを判断できます。
//問題1:m_timer.scheduleatfixedrate(new taskuselongtime()、1000、5000、timeunit.milliseconds); m_timer.scheduleatfixedrate(new tasknormal()、1000、5000、timeunit.milliseconds);ランニング結果:14:54:37:タスク通常実行14:54:37:タイマーが10秒眠っています14:54:42:タスク通常実行14:54:47:タスク通常実行14:54:47:タスク通常実行
質問2では、例外がスローされたときに、タスクの実行が他のタスクの操作に影響しないことがわかりました。同時に、私たちの例外は実行結果にスローされていないことがわかりました。これは、ScheduleThreadPoolexecutorクラスが、時限タスクを実行した後にスケジュールされたFutureの実行結果を返すためです。結果が成功したかどうかにかかわらず、例外があるかどうかは、ここで保存されます。
//問題2:m_timer.scheduleatfixedrate(new TaskThrowException()、1000、5000、TimeUnit.MilliseConds); m_timer.scheduleatfixedrate(new tasknormal()、1000、5000、timeunit.milliseconds);ランニング結果:14:58:36:スロー例外14:58:36:タスク通常実行14:58:41:タスク通常実行された14:58:46:実行されたタスク普通14:58:46:タスク通常実行
質問3マルチスレッドであるため、タイミングタスクを同時に実行できるようにすることができます。
//問題3:m_timer.scheduleatfixedrate(new taskuselongtime( "Timer1")、1000、5000、TimeUnit.milliseconds); m_timer.scheduleatfixedrate(new taskuselongtime( "timer2")、1000、5000、timeunit.milliseconds);ランニング結果:15:01:12:Timer1は10秒間眠っています15:01:12:Timer2は10秒眠っています15:01:22:Timer2は10秒眠っています15:01:22:Timer2は10秒眠っています15:01:22:Timer2は10秒眠っています10秒眠っています10秒15:01:22 15:01:22:Timer2は10秒眠っています15:01:22:Timer2は10秒眠っています15:01:22:Timer2は10秒眠っています15:01:22:Timer2は10秒眠っています15:01:22:Timer2は10秒眠っています15:01:22眠っています10秒眠っています14:01:22 15:01:22:Timer2は10秒間眠っています15:01:22:Timer2は10秒眠っています15:01:22:Timer2は10秒間眠っています15:01:22:Timer2は10秒眠っています15:01:22:Timer2は眠っています10秒15:01:01:01:01:01:01:01:01:01:01:01:01:01:01:01:01:01秒15:01:32:Timer2は10秒間眠っています
詳細なコード:
Package Timer_test; import java.text.simpledateformat; import java.util.date; import java.util.concurrent.callable; import java.util.concurrent.scheduledthreadpoolexceutor; Import java.util.current.timeunit; pribut class readedpooleexecotetote ScheduleDthreadPoolexecutor m_timer = new ScheduleDthreadPoolexecutor(10); public static void main(string [] args){schedulethreadpoolexecutortest temertest = new ScheduleToolexeCutortest(); timertest.test(); try {swreed.sleep {timertest.shutdown();}} public void shutdown(){m_timer.shutdown();} public void test(){//質問1:// m_timer.scheduleatfixedrate(new taskuselongtime()、1000、5000、5000、timeunit.milliseconds); // m_timer.scheduleatfixedrate(new tasknormal()、1000、5000、timeunit.milliseconds); //質問2:// m_timer.scheduleatfixedrate(new TaskThrowException()、1000、5000、TimeUnit.MilliseConds); // m_timer.scheduleatfixedrate(new tasknormal()、1000、5000、timeunit.milliseconds); //問題3:m_timer.scheduleatfixedrate(new taskuselongtime( "timer1")、1000、5000、timeunit.milliseconds); m_timer.scheduleatfixedrate(new taskuselongtime( "timer2")、1000、5000、Timeunit.millisecondss; callable <integer>、runnable {private string m_taskname = "timer"; private taskuselongtime(){} private taskuselongtime(string taskname){m_taskname = taskname;} public void run(){try {system.out.out.println(smotcurrenttime()sleeping()秒 "); swrep.sleep(10000);} catch(arturnedexception e){}} public integer call()throws exception {run(); return 0;}}@suppresswarnings(" unused ")プライベートクラスtasnormal実装<integer>、runable not exception() {system.out.println(getCurrentTime()+":task normountedexed");}}@suppresswarnings( "unused")private class taskthrowexceptionは呼ばれる<integer>、runnable {public integer call()throws {system.out.out.out.pubrintln()getcurrenttime() void run(){system.out.println(getCurrentTime()+":スロー例外"); new runtimeException();}} getCurrentTime(){return new SimpledateFormat( "HH:MM:SS")。要約します
上記は、Java Timersの開発史に関するこの記事の簡単な議論に関するものであり、すべての人に役立つことを願っています。興味のある友達は引き続きこのサイトを参照できます:
Javaは、シンプルなタイマーコードの解析を実装します
Javaマルチスレッドタイマータイマーの原則と実装
Javaタイマータイマーの使用方法のコード例
欠点がある場合は、それを指摘するためにメッセージを残してください。このサイトへのご支援をありがとうございました!