真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

springboot執(zhí)行延時任務(wù)中DelayQueue怎么用

這篇文章主要為大家展示了“springboot執(zhí)行延時任務(wù)中DelayQueue怎么用”,內(nèi)容簡而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領(lǐng)大家一起研究并學(xué)習(xí)一下“springboot執(zhí)行延時任務(wù)中DelayQueue怎么用”這篇文章吧。

永昌網(wǎng)站制作公司哪家好,找成都創(chuàng)新互聯(lián)公司!從網(wǎng)頁設(shè)計、網(wǎng)站建設(shè)、微信開發(fā)、APP開發(fā)、成都響應(yīng)式網(wǎng)站建設(shè)公司等網(wǎng)站項目制作,到程序開發(fā),運營維護。成都創(chuàng)新互聯(lián)公司公司2013年成立到現(xiàn)在10年的時間,我們擁有了豐富的建站經(jīng)驗和運維經(jīng)驗,來保證我們的工作的順利進行。專注于網(wǎng)站建設(shè)就選成都創(chuàng)新互聯(lián)公司。

DelayQueue簡介

DelayQueue是一個無界阻塞隊列,只有在延遲期滿時,才能從中提取元素。隊列的頭部,是延遲期滿后保存時間最長的delay元素。

在很多場景我們需要用到延時任務(wù),比如給客戶異步轉(zhuǎn)賬操作超時后發(fā)通知告知用戶,還有客戶下單后多長時間內(nèi)沒支付則取消訂單等等,這些都可以使用延時任務(wù)來實現(xiàn)。

jdk中DelayQueue可以實現(xiàn)上述需求,顧名思義DelayQueue就是延時隊列。

DelayQueue提供了在指定時間才能獲取隊列元素的功能,隊列頭元素是最接近過期的元素。

沒有過期元素的話,使用poll()方法會返回null值,超時判定是通過getDelay(TimeUnit.NANOSECONDS)方法的返回值小于等于0來判斷。

延時隊列不能存放空元素。

一般使用take()方法阻塞等待,有過期元素時繼續(xù)。

隊列元素說明

DelayQueue的隊列元素需要實現(xiàn)Delayed接口,該接口類定義如下:

public interface Delayed extends Comparable { /**  * Returns the remaining delay associated with this object, in the  * given time unit.  *  * @param unit the time unit  * @return the remaining delay; zero or negative values indicate  * that the delay has already elapsed  */ long getDelay(TimeUnit unit);}

所以DelayQueue的元素需要實現(xiàn)getDelay方法和Comparable接口的compareTo方法,getDelay方法來判定元素是否過期,compareTo方法來確定先后順序。

springboot中實例運用

DelayTask就是隊列中的元素

import java.util.Date;import java.util.concurrent.Delayed;import java.util.concurrent.TimeUnit;public class DelayTask implements Delayed { final private TaskBase data; final private long expire; /**  * 構(gòu)造延時任務(wù)  * @param data  業(yè)務(wù)數(shù)據(jù)  * @param expire 任務(wù)延時時間(ms)  */ public DelayTask(TaskBase data, long expire) {  super();  this.data = data;  this.expire = expire + System.currentTimeMillis(); } public TaskBase getData() {  return data; } public long getExpire() {  return expire; } @Override public boolean equals(Object obj) {  if (obj instanceof DelayTask) {   return this.data.getIdentifier().equals(((DelayTask) obj).getData().getIdentifier());  }  return false; } @Override public String toString() {  return "{" + "data:" + data.toString() + "," + "expire:" + new Date(expire) + "}"; } @Override public long getDelay(TimeUnit unit) {  return unit.convert(this.expire - System.currentTimeMillis(), unit); } @Override public int compareTo(Delayed o) {  long delta = getDelay(TimeUnit.NANOSECONDS) - o.getDelay(TimeUnit.NANOSECONDS);  return (int) delta; }}

TaskBase類是用戶自定義的業(yè)務(wù)數(shù)據(jù)基類,其中有一個identifier字段來標(biāo)識任務(wù)的id,方便進行索引

import com.alibaba.fastjson.JSON;public class TaskBase { private String identifier; public TaskBase(String identifier) {  this.identifier = identifier; } public String getIdentifier() {  return identifier; } public void setIdentifier(String identifier) {  this.identifier = identifier; } @Override public String toString() {  return JSON.toJSONString(this); }}

定義一個延時任務(wù)管理類DelayQueueManager,通過@Component注解加入到spring中管理,在需要使用的地方通過@Autowire注入

import com.alibaba.fastjson.JSON;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Value;import org.springframework.boot.CommandLineRunner;import org.springframework.stereotype.Component;import java.text.SimpleDateFormat;import java.util.Date;import java.util.concurrent.DelayQueue;import java.util.concurrent.Executors;@Componentpublic class DelayQueueManager implements CommandLineRunner { private final Logger logger = LoggerFactory.getLogger(DelayQueueManager.class); private DelayQueue delayQueue = new DelayQueue<>(); /**  * 加入到延時隊列中  * @param task  */ public void put(DelayTask task) {  logger.info("加入延時任務(wù):{}", task);  delayQueue.put(task); } /**  * 取消延時任務(wù)  * @param task  * @return  */ public boolean remove(DelayTask task) {  logger.info("取消延時任務(wù):{}", task);  return delayQueue.remove(task); } /**  * 取消延時任務(wù)  * @param taskid  * @return  */ public boolean remove(String taskid) {  return remove(new DelayTask(new TaskBase(taskid), 0)); } @Override public void run(String... args) throws Exception {  logger.info("初始化延時隊列");  Executors.newSingleThreadExecutor().execute(new Thread(this::excuteThread)); } /**  * 延時任務(wù)執(zhí)行線程  */ private void excuteThread() {  while (true) {   try {    DelayTask task = delayQueue.take();    processTask(task);   } catch (InterruptedException e) {    break;   }  } } /**  * 內(nèi)部執(zhí)行延時任務(wù)  * @param task  */ private void processTask(DelayTask task) {  logger.info("執(zhí)行延時任務(wù):{}", task);  //根據(jù)task中的data自定義數(shù)據(jù)來處理相關(guān)邏輯,例 if (task.getData() instanceof XXX) {} }}

DelayQueueManager實現(xiàn)了CommandLineRunner接口,在springboot啟動完成后就會自動調(diào)用run方法。

以上是“springboot執(zhí)行延時任務(wù)中DelayQueue怎么用”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對大家有所幫助,如果還想學(xué)習(xí)更多知識,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!


分享題目:springboot執(zhí)行延時任務(wù)中DelayQueue怎么用
文章鏈接:http://weahome.cn/article/gdjphj.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部