java定時器


一、@Scheduled注解

這是基於注解可實現定時任務。

實現:

1、

@EnableScheduling注解到定時方法的類上,或者直接注解到啟動類。

2、

@Scheduled注解到定時方法上
@Scheduled有以下參數:
1     @Scheduled(fixedDelay = 3000) //方法執行完成后等待3秒再次執行
2     @Scheduled(fixedRate = 3000)  //方法每隔3秒執行一次
3     @Scheduled(initialDelay = 2000,fixedRate = 4000) //延遲2秒執行第一次,之后每隔4秒執行一次
4     @Scheduled(fixedDelayString ="${time.demo}") //可以執行配置文件中的,方法執行完成后等待time.demo再次執行
5     @Scheduled(fixedRateString ="${time.demo}" ) //可以執行配置文件中的,法每隔time.demo執行一次
6     @Scheduled(cron = "0 0,30 0,8 ? * ? ")   //cron表達式,方法在每天的8點30分0秒執行,參數為字符串類型

cron表達式,推薦看這篇文章:https://www.jianshu.com/p/1defb0f22ed1

示例:

每隔3秒執行一次。

1 @Component
2 @EnableScheduling
3 public class testScheduled {
4     
5     @Scheduled(fixedRate = 3000)
6     public void call(){
7         System.out.println("每隔3秒打印一次");
8     }
9 }

優點:簡單,只需要兩個注解即可

缺點:參數和方法都必須寫到代碼里面

 

二、Timer().schedule創建任務

直接上示例,2秒后執行第一次,然后每隔4秒執行一次。

 1 @Component
 2 public class testTimer {
 3     {
 4         doTimer();
 5     }
 6     public void doTimer(){
 7         //創建timer對象
 8         Timer timer = new Timer();
 9         //創建TimerTask對象
10         TimerTask timerTask = new TimerTask() {
11             //重寫run方法,就是具體定時做什么事情
12             @Override
13             public void run() {
14                 System.out.println(new Date().toString());
15             }
16         };
17         //timer來執行timerTask
18         timer.schedule(timerTask,2000,4000);
19     }
20 }

幾個概念:

Timer:即定時器,為java自帶的工具類,提供定時執行任務的相關功能

timer有3個核心方法:

1、添加任務(6種)

schedule(TimerTask task, long delay):指定任務task,在delay毫秒延遲后執行
schedule(TimerTask task, Date time):指定任務task,在time時間點執行一次
schedule(TimerTask task, long delay, long period):指定任務task,延遲delay毫秒后執行第一次,並在之后每隔period毫秒執行一次
schedule(TimerTask task, Date firstTime, long period):指定任務task,在firstTime的時候執行第一次,之后每隔period毫秒執行一次
scheduleAtFixedRate(TimerTask task, long delay, long period):作用與schedule一致
scheduleAtFixedRate(TimerTask task, Date firstTime, long period):作用與schedule一致
實際上最后都會使用sched(TimerTask task, long time, long period),即指定任務task,在time執行第一次,之后每隔period毫秒執行一次

schedule使用系統時間計算下一次,即System.currentTimeMillis()+period

而scheduleAtFixedRate使用本次預計時間計算下一次,即time + period

對於耗時任務,兩者區別較大,請按需求選擇,瞬時任務無區別。

2、取消任務方法:cancel(),會將任務隊列清空,並堵塞線程,且不再能夠接受任務(接受時報錯),並不會銷毀本身的實例和其內部的線程。

3、凈化方法:purge(),凈化會將隊列里所有被取消的任務移除,對剩余任務進行堆排序,並返回移除任務的數量。

TimerTask:實際上就是一個Runnable而已,繼承Runnable並添加了幾個自定義的參數和方法,說白了就是在這里面寫定時的具體方法。

TaskQueue:即任務隊列,Timer生產任務,然后推到TaskQueue里存放,等待處理,被處理掉的任務即被移除掉。

注:TaskQueue實質上只有一個長度為128的數組用於存儲TimerTask、一個int型變量size表示隊列長度、以及對這兩個數據的增刪改查。

TimerThread:即定時器線程,線程會共享TaskQueue里面的數據,TimerThread會對TaskQueue里的任務進行消耗。

注:TimerThread實際上就是一個Thread線程,會不停的監聽TaskQueue,如果隊列里面有任務,那么就執行第一個,並將其刪除(先刪除再執行)。

三、線程

1、通過線程的sleep來造成延時的效果

示例1:thread + runnable

 1 @Component
 2 public class testThreadAndRunnable {
 3     
 4     private Integer count = 0;
 5     
 6     public testThreadAndRunnable() {
 7         test1();
 8     }
 9     public void test1() {
10         new Thread(() -> {
11             while (count < 10) {
12                 System.out.println(new Date().toString() + ": " + count);
13                 count++;
14                 try {
15                     Thread.sleep(3000);
16                 } catch (InterruptedException e) {
17                     e.printStackTrace();
18                 }
19             }
20         }).start();
21     }
22 }

示例2:線程池 + runnable

 1 @Component
 2 public class testThreadPool {
 3     private static final ExecutorService threadPool = Executors.newFixedThreadPool(5);// 線程池
 4     private Integer count = 0;
 5     public testThreadPool() {
 6         test2();
 7     }
 8     public void test2() {
 9         threadPool.execute(() -> {
10             while (count < 10) {
11                 System.out.println(new Date().toString() + ": " + count);
12                 count++;
13                 try {
14                     Thread.sleep(3000);
15                 } catch (InterruptedException e) {
16                     e.printStackTrace();
17                 }
18             }
19         });
20     }
21 }

 

2、使用ScheduledTask + runnable

示例:
@Component
public class testScheduledTask {
    private Integer count = 0;
    @Autowired
    private TaskScheduler taskScheduler;
    public testScheduledTask(TaskScheduler taskScheduler) {
        this.taskScheduler = taskScheduler;
        test4();
        test5();
        test6();
    }
    //設置間隔時間,每2秒執行一次
    public void test4() {
        taskScheduler.scheduleAtFixedRate(() -> {
            System.out.println(new Date().toString() + ": " + count+"設置間隔時間2秒");
            count++;
        }, 2000);
    }
    //可以用Cron表達式,每天凌晨1點執行
    public void test5() {
        taskScheduler.schedule(() -> {
            System.out.println(new Date().toString() + ": " + count+"凌晨1點執行");
            count++;
        }, new CronTrigger("0 0 1 * * ?"));
    }
    //設置間隔時間,每5.5秒執行一次
    public void test6() {
        taskScheduler.scheduleAtFixedRate(() -> {
            System.out.println(new Date().toString() + ": " + count+"設置間隔時間5.5秒");
            count++;
        }, 5500);
    }
}

 

四、Quartz

1、導入Quartz的jar包

        <dependency>
            <groupId>org.quartz-scheduler</groupId>
            <artifactId>quartz</artifactId>
            <version>2.3.2</version>
        </dependency>

2、實現的整體結構

2.1、創建定時任務對象的Job

//創建定時任務的對象
public class MyQuartz implements Job {
    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {

        Date date = new Date();
        String format = new SimpleDateFormat("yy-MM-dd HH-mm-ss").format(date);
        System.out.println("======響應時間為:"+format);
    }
}

2.2、創建執行類

@Component
public class MySchedule {
    public MySchedule() throws SchedulerException {
        doQ();
    }
    public void doQ() throws SchedulerException {
        //1、調度器Scheduler的創建
        Scheduler scheduler = new StdSchedulerFactory().getScheduler();
        //2、創建JobDetail實例,並綁定執行類
        JobDetail job = JobBuilder.newJob(MyQuartz.class).withIdentity("Quartz1", "QuartzGroup1").build();
        //3、構建Trigger實例
        CronTrigger build = TriggerBuilder.newTrigger().withIdentity("Trigger1", "QuartzTrigger1")
                .startNow()
                .withSchedule(CronScheduleBuilder.cronSchedule("2/3 * * * * ? *"))
                .build();
        //4、執行Quartz
        scheduler.scheduleJob(job,build);
        scheduler.start();
    }

corn表達式生成地址:https://cron.qqe2.com/

上述corn表達式指,2秒后開始執行,每3秒執行一次。

2.3、可以通過一些延時操作來控制任務停止時間

//5.利用TimeUnit實現延時操作
        TimeUnit.SECONDS.sleep(30);
        //6.關閉定時任務
        scheduler.shutdown();
        System.out.println("定時任務結束!");

Quartz參考博客:https://blog.csdn.net/qq_41011626/article/details/113740186

其他參考博客:(118條消息) 【JAVA定時器】四種常見定時器的原理和簡單實現_Echo-YeZi的博客-CSDN博客_java 定時器


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM