首頁 >Java >java教程 >Java單機環境怎麼實現定時任務

Java單機環境怎麼實現定時任務

王林
王林轉載
2023-04-18 12:16:031338瀏覽

定時任務框架

Java單機環境怎麼實現定時任務

TimeTask

從我們開始學習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執行任務只能串列執行,一旦一個任務執行的時間比較長的話將會影響其他任務執行

  • 執行任務過程如果發生異常,任務會直接停止。

隨著時間的推移,java的技術也在不斷的更新,針對TimeTask的不足,ScheduledExecutorService出現取代了TimeTask。

ScheduledExecutorService

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);
    }

缺點:

  • 盡量避免用Executors方式去建立線程池,因為jdk自帶執行緒池內部使用的的隊列的比較大,很容易出現OOM。

  • 定時任務是基於JVM單機記憶體形式的,一旦重啟定時任務就消失了。

  • 無法支援cron表達式實現豐富的定時任務。

Spring Task

學習了Spring之後,開始使用了Spring 自帶的Task。 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                   : Task Cron Expression:  Current Time  is     : Task Cron Expression:  Current Time  is     : Task Cron Expression:  Current Time  is     : Task Cron Expression:  Current Time  is  23:06:00 14604 --- [   scheduling -1] com.fw.task.SpringTask                   : Task with Initial Delay : Current Time is  23:06:22## 2022-04-06 23:06:06967:# fw .task.SpringTask                   : Fixed Rate Task :  Current Time  is  23:06:22
2022-04-06 23:06:06:22
2022-04-06 23:06:55 .task.SpringTask                   : Fixed Delay Task : Current Time  is  23:06:25
2022-04-06 23:06:25.955  INFO 14604 --- [   scheduling-1] com.fw.task.SpringTask  Current Time  is  23: 06:25
2022-04-06 23:06:27.555  INFO 14604 --- [   scheduling-1] com.fw.task.SpringTask    
2022-04-06 23:06:27.556  INFO 14604 --- [   scheduling-1] com.fw.task.SpringTask           1    

@ EnableScheduling需要開啟定時任務,@Scheduled(cron = "0/5 * * * * ?")配置定時任務的規則。 cron表達式支援豐富定時任務配置,不熟悉的可以查看

優點:

使用簡單方便,支援各種複雜的定時任務配置

缺點:

    基於單機形式定時任務,一旦重新啟動定時任務就消失了。
  • 定時任務預設是單執行緒執行任務,如果需要並行執行需要開啟@EnableAsync。
  • 沒有統一的圖形化任務排程的管理,無法控制定時任務

以上是Java單機環境怎麼實現定時任務的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:yisu.com。如有侵權,請聯絡admin@php.cn刪除