Java DelayQueue怎麼實現延時任務
一、DelayQueue的應用原理
DelayQueue是一個無界的BlockingQueue的實作類,用來放置實作了Delayed介面的對象,其中的物件只能在其到期時才能從佇列中取走。
BlockingQueue即阻塞佇列,java提供的面向多執行緒安全的佇列資料結構,當佇列內元素數量為0的時候,試圖從佇列內取得元素的執行緒將會被阻塞或拋出例外。
這裡的「無界」隊列,是指隊列的元素數量不存在上限,隊列的容量會隨著元素數量的增加而擴容。
DelayQueue實作了BlockingQueue接口,所以具有無界、阻塞的特點,除此之外它自己的核心特點就是:
##“放入該佇列的延時任務對象,只要到達延時時間之後才能被取到”。
DelayQueue 不接收null元素「DelayQueue 只接受那些實作了java.util.concurrent.Delayed介面的物件」
#二、訂單延時任務的實作了解了DelayQueue的特點之後,我們就可以利用它來實現延時任務了,實作java.util.concurrent.Delayed介面。
import org.jetbrains.annotations.NotNull; import java.text.SimpleDateFormat; import java.util.Date; import java.util.concurrent.Delayed; import java.util.concurrent.TimeUnit; /** * 延时订单任务 */ public class OrderDelayObject implements Delayed { private String name; private long delayTime; //延时时间 //实际业务中这里传订单信息对象,我这里只做demo,所以使用字符串了 private String order; public OrderDelayObject(String name, long delayTime, String order) { this.name = name; //延时时间加上当前时间 this.delayTime = System.currentTimeMillis() + delayTime; this.order = order; } //获取延时任务的倒计时时间 @Override public long getDelay(TimeUnit unit) { long diff = delayTime - System.currentTimeMillis(); return unit.convert(diff, TimeUnit.MILLISECONDS); } //延时任务队列,按照延时时间元素排序,实现Comparable接口 @Override public int compareTo(@NotNull Delayed obj) { return Long.compare(this.delayTime, ((OrderDelayObject) obj).delayTime); } @Override public String toString() { Date date = new Date(delayTime); SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); return "\nOrderDelayObject:{" + "name=" + name + ", time=" + sd.format(date) + ", order=" + order + "}"; } }上文類別中的order為訂單資訊對象,在實際的業務開發過程中應該是傳遞訂單訊息,用於取消訂單業務的實現(訂單30分鐘不付款自動取消)。 Delayed介面繼承自 Comparable接口,所以需要實作compareTo方法,用於延時任務在佇列中依照「延時時間」進行排序。 getDelay方法是Delayed介面方法,實作該方法提供取得延時任務的倒數計時時間三、訂單處理首先我們需要一個容器,永久保存延時任務隊列,如果是Spring開發環境我們可以這麼做。
@Bean("orderDelayQueue") public DelayQueue<OrderDelayObject> orderDelayQueue(){ return new DelayQueue<OrderDelayObject>(); }當用戶下單的時候,將訂單下單任務放入延時隊列
@Resource private DelayQueue<OrderDelayObject> orderDelayQueue; //发起订单下单的时候将订单演示对象放入orderDelayQueue orderDelayQueue.add( new OrderDelayObject( "订单延时取消任务", 30 * 60 * 1000, //延时30分钟 "延时任务订单对象信息" ) );系統內開啟一個線程,不斷的從隊列中獲取訊息,獲取到之後對延時訊息進行處理。
DelayQueue的take方法從佇列中取得延時任務對象,如果佇列元素數量為0,或沒有到達“延時時間的任務”,則該執行緒會被阻塞。
@Component public class DelayObjectConsumer implements InitializingBean { @Resource private DelayQueue<OrderDelayObject> orderDelayQueue; @Override public void afterPropertiesSet() throws Exception { while (true) { OrderDelayObject task = orderDelayQueue.take(); System.out.println(task.toString()); System.out.println(task.getOrder()); //根据order订单信息,去查询该订单的支付信息 //如果用户没有进行支付,将订单从数据库中关闭 //如果订单并发量比较大,这里可以考虑异步或线程池的方式进行处理 } } }需要說明的是,這裡的while-true循環的延時任務處理是順序執行的,在訂單並發量比較大的時候,需要考慮非同步處理的方式完成訂單的關閉操作。我之前寫過一個SpringBoot的可觀測、易配置的線程池開源項目,可能會對你有幫助,源代碼地址經過我的測試,放入orderDelayQueue的延時任務,在半小時之後得到正確的執行處理。說明我們的實作是正確的。 四、優缺點使用DelayQueue實現延時任務非常簡單,而且簡便,全部都是標準的JDK程式碼實現,不用引入第三方依賴(不依賴redis實作、訊息佇列實現等),非常的輕量級。 它的缺點就是所有的操作都是基於應用記憶體的,一旦出現應用單點故障,可能會造成延時任務資料的遺失。如果訂單並發量非常大,因為DelayQueue是無界的,訂單量越大,佇列內的物件就越多,可能造成OOM的風險。所以使用DelayQueue實現延時任務,只適用於任務量較小的情況。
以上是Java DelayQueue怎麼實現延時任務的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undress AI Tool
免費脫衣圖片

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

前形式攝取,quarkusandmicronautleaddueTocile timeProcessingandGraalvSupport,withquarkusoftenpernperforminglightbetterine nosserless notelless centarios.2。

First,checkiftheFnkeysettingisinterferingbytryingboththevolumekeyaloneandFn volumekey,thentoggleFnLockwithFn Escifavailable.2.EnterBIOS/UEFIduringbootandenablefunctionkeysordisableHotkeyModetoensurevolumekeysarerecognized.3.Updateorreinstallaudiodriv

使用.equals()方法比較字符串內容,因為==僅比較對象引用而非內容;1.使用.equals()比較字符串值是否相等;2.使用.equalsIgnoreCase()進行忽略大小寫的比較;3.使用.compareTo()按字典順序比較字符串,返回0、負數或正數;4.使用.compareToIgnoreCase()進行忽略大小寫的字典序比較;5.使用Objects.equals()或安全調用方式處理null字符串,避免空指針異常。總之,應避免使用==進行字符串內容比較,除非明確需要檢查對像是否相

使用String.join()(Java8 )是連接字符串數組最簡單推薦的方法,直接指定分隔符即可;2.對於舊版本Java或需要更多控制時,可使用StringBuilder手動遍歷並拼接;3.StringJoiner適用於需要前綴、後綴等更靈活格式的場景;4.使用Arrays.stream()結合Collectors.joining()適合在連接前對數組進行過濾或轉換等操作;綜上所述,若使用Java8及以上版本,大多數情況下應首選String.join()方法,語法簡潔易讀,而對於復雜邏輯則推薦

Python的logging模塊可通過FileHandler將日誌寫入文件,首先調用basicConfig配置文件處理器和格式,如設置level為INFO、使用FileHandler寫入app.log;其次可添加StreamHandler實現同時輸出到控制台;進階場景可用TimedRotatingFileHandler按時間分割日誌,例如設置when='midnight'實現每日生成新文件並保留7天備份,需確保日誌目錄存在;建議使用getLogger(__name__)創建命名logger,生產

在JupyterNotebook中使用PandasStyling可實現DataFrame的美觀展示,1.使用highlight_max和highlight_min高亮每列最大值(綠色)和最小值(紅色);2.通過background_gradient為數值列添加漸變背景色(如Blues或Reds)以直觀顯示數據大小;3.自定義函數color_score結合applymap為不同分數區間設置文字顏色(≥90綠色,80~89橙色,60~79紅色,

computed有緩存,依賴不變時多次訪問不重新計算,而methods每次調用都執行;2.computed適用於基於響應式數據的計算,methods適合需要參數或頻繁調用但結果不依賴響應式數據的場景;3.computed支持getter和setter,可實現數據的雙向同步,methods不支持;4.總結:優先使用computed以提升性能,當需要傳參、執行操作或避免緩存時使用methods,遵循“能用computed就不用methods”的原則。

testthepdfinanotherapptoderineiftheissueiswiththefileoredge.2.enablethebuilt inpdfviewerbyTurningOff“ eflblyopenpenpenpenpenpdffilesexternally”和“ downloadpdffiles” inedgesettings.3.clearbrowsingdatainclorwearbrowsingdataincludingcookiesandcachedcachedfileresteroresoreloresorelorsolesoresolesoresolvereresoreorsolvereresoreolversorelesoresolvererverenn
