本文目錄一覽:
java怎麼用定時任務實現失效
1、ZSet 實現方式
通過 ZSet 實現定時任務的思路是,將定時任務存放到 ZSet 集合中,並且將過期時間存儲到 ZSet 的 Score 欄位中,然後通過一個無線循環來判斷當前時間內是否有需要執行的定時任務,如果有則進行執行,具體實現代碼如下:
import redis.clients.jedis.Jedis;
import utils.JedisUtils;
import java.time.Instant;
import java.util.Set;
public class DelayQueueExample {
private static final String _KEY = “DelayQueueExample”;
public static void main(String[] args) throws InterruptedException {
Jedis jedis = JedisUtils.getJedis();
// 30s 後執行
long delayTime = Instant.now().plusSeconds(30).getEpochSecond();
jedis.zadd(_KEY, delayTime, “order_1”);
// 繼續添加測試數據
jedis.zadd(_KEY, Instant.now().plusSeconds(2).getEpochSecond(), “order_2”);
jedis.zadd(_KEY, Instant.now().plusSeconds(2).getEpochSecond(), “order_3”);
jedis.zadd(_KEY, Instant.now().plusSeconds(7).getEpochSecond(), “order_4”);
jedis.zadd(_KEY, Instant.now().plusSeconds(10).getEpochSecond(), “order_5”);
// 開啟定時任務隊列
doDelayQueue(jedis);
}
/**
* 定時任務隊列消費
* @param jedis Redis 客戶端
*/
public static void doDelayQueue(Jedis jedis) throws InterruptedException {
while (true) {
// 當前時間
Instant nowInstant = Instant.now();
long lastSecond = nowInstant.plusSeconds(-1).getEpochSecond();
// 上一秒時間
long nowSecond = nowInstant.getEpochSecond();
// 查詢當前時間的所有任務
Set data = jedis.zrangeByScore(_KEY, lastSecond, nowSecond);
for (String item : data) {
// 消費任務
System.out.println(“消費:” + item);
}
// 刪除已經執行的任務
jedis.zremrangeByScore(_KEY, lastSecond, nowSecond);
Thread.sleep(1000); // 每秒查詢一次
}
}
}
登錄後複製

2、鍵空間通知
我們可以通過 Redis 的鍵空間通知來實現定時任務,它的實現思路是給所有的定時任務設置一個過期時間,等到了過期之後,我們通過訂閱過期消息就能感知到定時任務需要被執行了,此時我們執行定時任務即可。
默認情況下 Redis 是不開啟鍵空間通知的,需要我們通過 config set notify-keyspace-events Ex 的命令手動開啟,開啟之後定時任務的代碼如下
java 定時任務的幾種實現方式
JDK 自帶的定時器實現
// schedule(TimerTask task, long delay) 延遲 delay 毫秒 執行
// schedule(TimerTask task, Date time) 特定時間執行
public static void main(String[] args) {
for (int i = 0; i 10; ++i) {
new Timer(“timer – ” + i).schedule(new TimerTask() {
@Override
public void run() {
println(Thread.currentThread().getName() + ” run “);
}
}, 1000);
}
}
2. Quartz 定時器實現
//首先我們需要定義一個任務類,比如為MyJob02 ,
//該類需要繼承Job類,然後添加execute(JobExecutionContext context)方法,在
//這個方法中就是我們具體的任務執行的地方。
//由希望由調度程序執行的組件實現的介面
public class MyJob02 implements Job {
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
// TODO Auto-generated method stub
// 執行響應的任務.
System.out.println(“HelloJob.execute,”+new Date());
}
}
public class QuartzTest5 {
public static void main(String[] args) throws Exception {
//SchedulerFactory 是一個介面,用於Scheduler的創建和管理
SchedulerFactory factory = new StdSchedulerFactory();
//從工廠裡面拿到一個scheduler實例
//計劃表(可能翻譯的不太貼切),現在我們有了要做的內容,
//與調度程序交互的主要API
/*
* Scheduler的生命期,從SchedulerFactory創建它時開始,
到Scheduler調用shutdown()方法時結束;Scheduler被創建後,
可以增加、刪除和列舉Job和Trigger,以及執行其它與調度相關的操作
(如暫停Trigger)。但是,Scheduler只有在調用start()方法後,
才會真正地觸發trigger(即執行job)
*/
Scheduler scheduler = factory.getScheduler();
//具體任務.
//用於定義作業的實例
//JobBuilder – 用於定義/構建JobDetail實例,用於定義作業的實例。
JobDetail job = JobBuilder.newJob(MyJob.class).withIdentity(“job1”, “group1”).build();
//Trigger(即觸發器) – 定義執行給定作業的計劃的組件
//TriggerBuilder – 用於定義/構建觸發器實例
CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(“trigger1”, “group1”)
.withSchedule(CronScheduleBuilder.cronSchedule(“0/1 * * * * ?”)).build();
scheduler.scheduleJob(job, trigger);
scheduler.start();
}
3. Spring boot 任務調度(這個非常容易實現)
/*
* 開啟對定時任務的支持
* 在相應的方法上添加@Scheduled聲明需要執行的定時任務。
*/
@EnableScheduling
//@EnableScheduling註解來開啟對計劃任務的支持
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
@Component
public class ScheduledTasks {
private Logger logger = LoggerFactory.getLogger(ScheduledTasks.class);
private int i=0;
//0 0 0 2 * ?
@Scheduled(cron=”* * * 2 * ?”)
//@Scheduled 註解用於標註這個方法是一個定時任務的方法
public void testFixDelay() {
logger.info(“執行方法”+i++);
}
JAVA實現定時任務的幾種方式
Java 基本的定時任務,總結方法有三種:
1 創建一個thread,然後讓它在while循環里一直運行著,通過sleep方法來達到定時任務的效果;
2 用Timer和TimerTask與第一種方法相比有如下好處:
當啟動和去取消任務時可以控制
第一次執行任務時可以指定你想要的delay時間
3 用ScheduledExecutorService是從的java.util.concurrent里,做為並發工具類被引進的,這是最理想的定時任務實現方式,相比於上兩個方法,它有以下好處:
相比於Timer的單線程,它是通過線程池的方式來執行任務的
可以很靈活的去設定第一次執行任務delay時間
提供了良好的約定,以便設定執行的時間間隔
java定時任務沒有執行完又到執行時間了
代碼錯誤。多數是代碼錯誤導致java定時任務沒有執行完又到執行時間了。
1、首先打開java檢查代碼是否錯誤。
2、其次打開網路診斷器進行測試網路連接是否異常。
3、最後點擊重新運行java即可。
原創文章,作者:RAWZ,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/137479.html