欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

springboot執(zhí)行延時(shí)任務(wù)之DelayQueue的使用詳解

 更新時(shí)間:2019年12月12日 12:44:49   作者:依天照海  
DelayQueue是一個(gè)無(wú)界阻塞隊(duì)列,只有在延遲期滿時(shí),才能從中提取元素。這篇文章主要介紹了springboot執(zhí)行延時(shí)任務(wù)-DelayQueue的使用,需要的朋友可以參考下

DelayQueue簡(jiǎn)介

DelayQueue是一個(gè)無(wú)界阻塞隊(duì)列,只有在延遲期滿時(shí),才能從中提取元素。
隊(duì)列的頭部,是延遲期滿后保存時(shí)間最長(zhǎng)的delay元素。

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

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

DelayQueue提供了在指定時(shí)間才能獲取隊(duì)列元素的功能,隊(duì)列頭元素是最接近過(guò)期的元素。

沒(méi)有過(guò)期元素的話,使用poll()方法會(huì)返回null值,超時(shí)判定是通過(guò)getDelay(TimeUnit.NANOSECONDS)方法的返回值小于等于0來(lái)判斷。

延時(shí)隊(duì)列不能存放空元素。

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

隊(duì)列元素說(shuō)明

DelayQueue<E extends Delayed>的隊(duì)列元素需要實(shí)現(xiàn)Delayed接口,該接口類定義如下:

public interface Delayed extends Comparable<Delayed> {

 /**
  * 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的元素需要實(shí)現(xiàn)getDelay方法和Comparable接口的compareTo方法,getDelay方法來(lái)判定元素是否過(guò)期,compareTo方法來(lái)確定先后順序。

springboot中實(shí)例運(yùn)用

DelayTask就是隊(duì)列中的元素

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)造延時(shí)任務(wù)
  * @param data  業(yè)務(wù)數(shù)據(jù)
  * @param expire 任務(wù)延時(shí)時(shí)間(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ù)基類,其中有一個(gè)identifier字段來(lái)標(biāo)識(shí)任務(wù)的id,方便進(jìn)行索引

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

定義一個(gè)延時(shí)任務(wù)管理類DelayQueueManager,通過(guò)@Component注解加入到spring中管理,在需要使用的地方通過(guò)@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;
@Component
public class DelayQueueManager implements CommandLineRunner {
 private final Logger logger = LoggerFactory.getLogger(DelayQueueManager.class);
 private DelayQueue<DelayTask> delayQueue = new DelayQueue<>();
 /**
  * 加入到延時(shí)隊(duì)列中
  * @param task
  */
 public void put(DelayTask task) {
  logger.info("加入延時(shí)任務(wù):{}", task);
  delayQueue.put(task);
 }
 /**
  * 取消延時(shí)任務(wù)
  * @param task
  * @return
  */
 public boolean remove(DelayTask task) {
  logger.info("取消延時(shí)任務(wù):{}", task);
  return delayQueue.remove(task);
 }
 /**
  * 取消延時(shí)任務(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("初始化延時(shí)隊(duì)列");
  Executors.newSingleThreadExecutor().execute(new Thread(this::excuteThread));
 }
 /**
  * 延時(shí)任務(wù)執(zhí)行線程
  */
 private void excuteThread() {
  while (true) {
   try {
    DelayTask task = delayQueue.take();
    processTask(task);
   } catch (InterruptedException e) {
    break;
   }
  }
 }
 /**
  * 內(nèi)部執(zhí)行延時(shí)任務(wù)
  * @param task
  */
 private void processTask(DelayTask task) {
  logger.info("執(zhí)行延時(shí)任務(wù):{}", task);
  //根據(jù)task中的data自定義數(shù)據(jù)來(lái)處理相關(guān)邏輯,例 if (task.getData() instanceof XXX) {}
 }
}

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

總結(jié)

以上所述是小編給大家介紹的springboot執(zhí)行延時(shí)任務(wù)DelayQueue的使用詳解,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
如果你覺(jué)得本文對(duì)你有幫助,歡迎轉(zhuǎn)載,煩請(qǐng)注明出處,謝謝!

相關(guān)文章

  • Java 如何實(shí)現(xiàn)時(shí)間控制

    Java 如何實(shí)現(xiàn)時(shí)間控制

    這篇文章主要向大家介紹得是Java 如何實(shí)現(xiàn)時(shí)間控制,文章珠岙舉例說(shuō)明該內(nèi)容,感興趣得小伙伴可以跟小編一起學(xué)習(xí)下面文章內(nèi)容
    2021-10-10
  • 使用springboot訪問(wèn)圖片本地路徑并映射成url

    使用springboot訪問(wèn)圖片本地路徑并映射成url

    這篇文章主要介紹了使用springboot訪問(wèn)圖片本地路徑并映射成url的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • Java并發(fā)編程信號(hào)量Semapher

    Java并發(fā)編程信號(hào)量Semapher

    這篇文章主要介紹了Java并發(fā)編程信號(hào)量Semapher,Semapher信號(hào)量也是Java中的一個(gè)同步器,下文關(guān)于信號(hào)量Semapher的更多內(nèi)容介紹,需要的小伙伴可以參考下面文章
    2022-04-04
  • IDEA配置tomcat的方法、IDEA配置tomcat運(yùn)行web項(xiàng)目詳解

    IDEA配置tomcat的方法、IDEA配置tomcat運(yùn)行web項(xiàng)目詳解

    這篇文章主要介紹了IDEA配置tomcat的方法、IDEA配置tomcat運(yùn)行web項(xiàng)目詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • Mybatis分頁(yè)的實(shí)現(xiàn)及使用注解開(kāi)發(fā)操作

    Mybatis分頁(yè)的實(shí)現(xiàn)及使用注解開(kāi)發(fā)操作

    這篇文章主要介紹了Mybatis分頁(yè)的實(shí)現(xiàn)及使用注解開(kāi)發(fā)操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • Java 實(shí)現(xiàn)滑動(dòng)時(shí)間窗口限流算法的代碼

    Java 實(shí)現(xiàn)滑動(dòng)時(shí)間窗口限流算法的代碼

    這篇文章主要介紹了Java 實(shí)現(xiàn)滑動(dòng)時(shí)間窗口限流算法的代碼,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-11-11
  • java中equals和等號(hào)(==)的區(qū)別淺談

    java中equals和等號(hào)(==)的區(qū)別淺談

    java中equals和等號(hào)(==)的區(qū)別淺談,需要的朋友可以參考一下
    2013-05-05
  • JAVA如何調(diào)用Shell腳本

    JAVA如何調(diào)用Shell腳本

    本篇文章主要介紹了JAVA如何調(diào)用Shell腳本,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-08-08
  • 淺談Java并發(fā)編程之Lock鎖和條件變量

    淺談Java并發(fā)編程之Lock鎖和條件變量

    這篇文章主要介紹了淺談Java并發(fā)編程之Lock鎖和條件變量,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08
  • 關(guān)于SpringBoot的自動(dòng)裝配原理詳解

    關(guān)于SpringBoot的自動(dòng)裝配原理詳解

    這篇文章主要介紹了關(guān)于SpringBoot的自動(dòng)裝配原理詳解,Spring?Boot自動(dòng)裝配原理是指Spring?Boot在啟動(dòng)時(shí)自動(dòng)掃描項(xiàng)目中的依賴關(guān)系,根據(jù)依賴關(guān)系自動(dòng)配置相應(yīng)的Bean,從而簡(jiǎn)化了Spring應(yīng)用的配置過(guò)程,需要的朋友可以參考下
    2023-07-07

最新評(píng)論