ホームページ >Java >&#&チュートリアル >Java スタンドアロン環境でスケジュールされたタスクを実装する方法
Java の学習を開始して以来、スケジュールされたタスクを初めて実装するのは TimeTask であり、Timer が使用されました。 TaskQueue クラスは、スケジュールされたタスクを格納し、最小限のヒープ実装に基づいた優先キューです。 TaskQueue は、タスク間の距離と次の実行時間に基づいてタスクを並べ替え、ヒープの一番上にあるタスクが最初に実行されるようにします。
サンプルコード:
public static void main(String[] args) { TimerTask task = new TimerTask() { public void run() { System.out.println("当前时间: " + new Date() + "n" + "线程名称: " + Thread.currentThread().getName()); } }; Timer timer = new Timer("Timer"); long delay = 5000L; timer.schedule(task, delay); System.out.println("当前时间: " + new Date() + "n" + "线程名称: " + Thread.currentThread().getName()); }
実行結果:
当前时间: Wed Apr 06 22:05:04 CST 2022n线程名称: main 当前时间: Wed Apr 06 22:05:09 CST 2022n线程名称: Timer
結果からわかるように、スケジュールされたタスクは 5 秒後に実行されました。
欠点:
TimeTask 実行タスクは連続的にのみ実行できます。1 つのタスクの実行に時間がかかると、実行に影響します。
タスクの実行中に例外が発生した場合、タスクは直接停止します。
時間の経過とともに、Java テクノロジーは常に更新されており、TimeTask の欠点に対応して、ScheduledExecutorService が TimeTask を置き換えるようになっています。
ScheduledExecutorService は、複数の実装クラスを持つインターフェイスであり、より一般的に使用されるのは ScheduledThreadPoolExecutor です。 ScheduledThreadPoolExecutor 自体はスレッド プールであり、内部で DelayQueue をタスク キューとして使用し、タスクの同時実行をサポートします。
コード例:
public static void main(String[] args) throws InterruptedException { ScheduledExecutorService executorService = Executors.newScheduledThreadPool(3); // 执行任务: 每 10秒执行一次 executorService.scheduleAtFixedRate(() -> { System.out.println("执行任务:" + new Date()+",线程名称: " + Thread.currentThread().getName()); }, 1, 10, TimeUnit.SECONDS); }
欠点:
エグゼキューターを使用してスレッドを作成することは避けてください。プールは、jdkのスレッドプールで内部的に使用されるキューが比較的大きいため、OOMが発生しやすいです。
スケジュールされたタスクは JVM スタンドアロン メモリに基づいており、スケジュールされたタスクは再起動されると消えます。
豊富なスケジュールされたタスクを実装するための cron 式をサポートできません。
Spring を学習した後、Spring 独自のタスクを使い始めました。 Spring Framework にはスケジュールされたタスクが付属しており、豊富なスケジュールされたタスク構成を実装するための cron 式が提供されます。
インスタンス コード:
@EnableScheduling @Component public class SpringTask { private Logger logger = LoggerFactory.getLogger(SpringTask.class); private static final SimpleDateFormat dateFormat = new SimpleDateFormat( "HH:mm:ss"); /** * fixedRate:固定速率执行。每5秒执行一次。 */ @Scheduled(fixedRate = 5000) public void invokeTaskWithFixedRate() { logger.info("Fixed Rate Task : Current Time is {}", dateFormat.format(new Date())); } /** * fixedDelay:固定延迟执行。距离上一次调用成功后2秒才执。 */ @Scheduled(fixedDelay = 2000) public void invokeTaskWithFixedDelay() { try { TimeUnit.SECONDS.sleep(3); logger.info("Fixed Delay Task : Current Time is {}", dateFormat.format(new Date())); } catch (InterruptedException e) { logger.error("invoke task error",e); } } /** * initialDelay:初始延迟。任务的第一次执行将延迟5秒,然后将以5秒的固定间隔执行。 */ @Scheduled(initialDelay = 5000, fixedRate = 5000) public void invokeTaskWithInitialDelay() { logger.info("Task with Initial Delay : Current Time is {}", dateFormat.format(new Date())); } /** * cron:使用Cron表达式,每隔5秒执行一次 */ @Scheduled(cron = "0/5 * * * * ? ") public void invokeTaskWithCronExpression() { logger.info("Task Cron Expression: Current Time is {}", dateFormat.format(new Date())); } }
実行結果:
2022-04-06 23:06:20.945 INFO 14604 --- [ scheduling-1] com.fw.task.SpringTask : タスク Cron 式: 現在の時刻は 23:06:20
2022-04-06 23:06:22.557 INFO 14604 --- [ スケジューリング-1] com.fw.task.SpringTask : 初期遅延のあるタスク : 現在の時刻は 23:06:22
2022-04-06 23:06:22.557 INFO 14604 --- [scheduling-1] com.fw .task.SpringTask : 固定レートのタスク : 現在の時刻は 23:06:22
2022-04-06 23:06:25.955 INFO 14604 --- [ scheduling-1] com.fw.task.SpringTask : 固定遅延タスク: 現在の時刻は 23:06:25
2022-04-06 23:06:25.955 INFO 14604 --- [scheduling-1] com.fw.task.SpringTask: タスク Cron 式: 現在の時刻は 23: 06:25
2022-04-06 23:06:27.555 INFO 14604 --- [scheduling-1] com.fw.task.SpringTask : 初期遅延のあるタスク : 現在の時刻は 23:06:27
2022-04-06 23:06:27.556 INFO 14604 --- [scheduling-1] com.fw.task.SpringTask : 固定レート タスク : 現在の時刻は 23:06:27
@ ですEnableScheduling はスケジュールされたタスクを有効にする必要があり、 @Scheduled(cron = "0/5 * * * * ?") はスケジュールされたタスクのルールを構成します。 cron 式は豊富なスケジュールされたタスク構成をサポートしています。詳しくない場合は、次の点を確認してください。
利点:
シンプルで使いやすく、サポートされています。さまざまな複雑なスケジュールされたタスクの構成
欠点:
スタンドアロンのスケジュールされたタスクに基づいており、スケジュールされたタスクは再起動すると消えます。
スケジュールされたタスクのデフォルトはシングルスレッド実行タスクです。並列実行が必要な場合は、@EnableAsync をオンにする必要があります。
統合されたグラフィカルなタスク スケジュール管理がなければ、スケジュールされたタスクを制御できません
以上がJava スタンドアロン環境でスケジュールされたタスクを実装する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。