在實踐中使用延遲隊列

通常,在某些情況下,當您有某種工作或作業隊列時,有必要不立即處理每個工作項或作業,而是要延遲一些時間。 例如,如果用戶單擊一個按鈕來觸發要完成的某項工作,而一秒鐘后,用戶意識到他/她錯了,則該工作根本就不會開始。 或者,如果有一個用例,則在經過一些延遲(過期)后應刪除隊列中的某些工作元素。

有很多實現,但是我想描述的是使用純JDK并發框架類: DelayedQueue和Delayed接口。

讓我從定義工作項的簡單(且為空)界面開始。 我跳過諸如屬性和方法之類的實現細節,因為它們并不重要。

package com.example.delayed;public interface WorkItem {// Some properties and methods here
}

我們模型中的下一個類將代表被推遲的工作項并實現Delayed接口。 僅有幾個基本概念需要考慮:延遲本身和相應工作項已提交的實際時間。 這就是到期日的計算方式。 因此,我們通過引入PostponedWorkItem類來做到這一點。

package com.example.delayed;import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;public class PostponedWorkItem implements Delayed {private final long origin;private final long delay;private final WorkItem workItem;public PostponedWorkItem( final WorkItem workItem, final long delay ) {this.origin = System.currentTimeMillis();this.workItem = workItem;this.delay = delay;}@Overridepublic long getDelay( TimeUnit unit ) {return unit.convert( delay - ( System.currentTimeMillis() - origin ), TimeUnit.MILLISECONDS );}@Overridepublic int compareTo( Delayed delayed ) {if( delayed == this ) {return 0;}if( delayed instanceof PostponedWorkItem ) {long diff = delay - ( ( PostponedWorkItem )delayed ).delay;return ( ( diff == 0 ) ? 0 : ( ( diff < 0 ) ? -1 : 1 ) );}long d = ( getDelay( TimeUnit.MILLISECONDS ) - delayed.getDelay( TimeUnit.MILLISECONDS ) );return ( ( d == 0 ) ? 0 : ( ( d < 0 ) ? -1 : 1 ) );}
}

如您所見,我們創建該類的新實例,并將當前系統時間保存在內部origin屬性中。 getDelayed方法計算工作項過期之前剩余的實際時間。 延遲是外部設置,它是構造函數參數。 由于Delayed擴展了此接口,因此必須強制實施Comparable <Delayed> 。

現在,我們大部分完成了! 為了完成該示例,讓我們通過實現equalshashCode來確保不會將相同的工作項兩次提交到工作隊列中(實現非常簡單,不需要任何注釋)。

public class PostponedWorkItem implements Delayed {...@Overridepublic int hashCode() {final int prime = 31;int result = 1;result = prime * result + ( ( workItem == null ) ? 0 : workItem.hashCode() );return result;}@Overridepublic boolean equals( Object obj ) {if( this == obj ) {return true;}if( obj == null ) {return false;}if( !( obj instanceof PostponedWorkItem ) ) {return false;}final PostponedWorkItem other = ( PostponedWorkItem )obj;if( workItem == null ) {if( other.workItem != null ) {return false;}} else if( !workItem.equals( other.workItem ) ) {return false;}return true;}
}

最后一步是引入某種管理器,該管理器將安排工作項并定期輪詢過期的項:見WorkItemScheduler類。

package com.example.delayed;import java.util.ArrayList;
import java.util.Collection;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.DelayQueue;public class WorkItemScheduler {private final long delay = 2000; // 2 secondsprivate final BlockingQueue< PostponedWorkItem > delayed =new DelayQueue< PostponedWorkItem >(); public void addWorkItem( final WorkItem workItem ) {final PostponedWorkItem postponed = new PostponedWorkItem( workItem, delay );if( !delayed.contains( postponed )) {delayed.offer( postponed );}}public void process() {final Collection< PostponedWorkItem > expired = new ArrayList< PostponedWorkItem >();delayed.drainTo( expired );for( final PostponedWorkItem postponed: expired ) {// Do some real work here with postponed.getWorkItem()}}
}

使用BlockingQueue可以確保線程安全和高級別的并發性。 該處理方法應定期運行,以排干工作項隊列。 它可以通過Spring Framework中的@ Scheduled注釋或JEE 6中的 EJB的@Schedule注釋進行注釋。

請享用!

參考:在Andriy Redko {devmind}博客上,我們的JCG合作伙伴 Andriy Redko 在實踐中使用了延遲隊列 。


翻譯自: https://www.javacodegeeks.com/2012/04/using-delayed-queues-in-practice.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/372852.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/372852.shtml
英文地址,請注明出處:http://en.pswp.cn/news/372852.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

PCL學習八叉樹

建立空間索引在點云數據處理中有著廣泛的應用&#xff0c;常見的空間索引一般 是自頂而下逐級劃分空間的各種空間索引結構&#xff0c;比較有代表性的包括BSP樹&#xff0c;KD樹&#xff0c;KDB樹&#xff0c;R樹&#xff0c;四叉樹&#xff0c;八叉樹等索引結構&#xff0c;而…

Android實現自定義帶文字和圖片的Button

在Android開發中經常會需要用到帶文字和圖片的button&#xff0c;下面來講解一下常用的實現辦法。 一.用系統自帶的Button實現 最簡單的一種辦法就是利用系統自帶的Button來實現&#xff0c;這種方式代碼量最小。在Button的屬性中有一個是drawableLeft&#xff0c;這個 屬性可以…

mysql語句中的注釋方法_MySQL語句注釋方式簡介

MySQL支持三種注釋方式&#xff1a;1.從‘#字符從行尾。2.從‘-- 序列到行尾。請注意‘-- (雙破折號)注釋風格要求第2個破折號后面至少跟一個空格符(例如空格、tab、換行符等等)。3.從/*序列到后面的*/序列。結束序列不一定在同一行中&#xff0c;因此該語法允許注釋跨越多行。…

aqlserver實用程序_sqlserver命令提示實用工具的介紹

除上述的圖形化管理工具外&#xff0c;SQL Server2008還提供了大量的命令行實用工具&#xff0c;包括bcp、dtexec、dtutil、osql、reconfig、sqlcmd、sqlwb和tablediff等&#xff0c;下面進行簡要說明。dtexec實用工具用于配置和執行SQL Server2008 Intgration Services包。用戶…

使用Java和Scala將Play Framework 2應用程序部署到Openshift

幾個星期&#xff0c; 馬克阿特伍德 &#xff08; Mark Atwood&#xff09; &#xff0c; 豪爾赫阿里斯 &#xff08; Jorge Aliss &#xff09;和我塞巴斯蒂安 斯卡塔諾 &#xff08; SebastinScarano&#xff09;參加了紅帽網絡研討會LETS PLAY&#xff01; 在云端&#xff1…

LintCode 387: Smallest Difference

LintCode 387: Smallest Difference 題目描述 給定兩個整數數組&#xff08;第一個是數組A&#xff0c;第二個是數組B&#xff09;&#xff0c;在數組A中取A[i]&#xff0c;數組B中取B[j]&#xff0c;A[i]和B[j]兩者的差越小越好(|A[i] - B[j]|)。返回最小差。 樣例 給定數組A …

android框架----下沉文字Titanic的使用

Titanic is a simple illusion obtained by applying an animated translation on the TextView TextPaint Shaders matrix. Titanic的使用 Titanic的使用&#xff0c;項目結構如下&#xff1a; 一、下載Titanic并且部署到項目中 Titanic的項目地址&#xff1a; https://github…

linux 自動安裝mysql_Linux安裝mysql

一、下載這里我創建了一目錄software用于存放我們待會要下載的mysql包&#xff0c;先去到該目錄命令&#xff1a;cd /software命令&#xff1a;wget http://mirrors.sohu.com/mysql/MySQL-5.7/mysql-5.7.17-linux-glibc2.5-x86_64.tar下載完成后&#xff0c;你會在software這個…

Quartz Scheduler插件–隱藏的寶藏

盡管在官方文檔中進行了簡要描述&#xff0c;但我相信Quartz插件了解得還不夠多&#xff0c;看看它們有多有用。 本質上&#xff0c;Quartz中的插件是方便的類&#xff0c;用于包裝基礎偵聽器的注冊。 您可以自由編寫自己的插件&#xff0c;但我們將專注于Quartz隨附的現有插件…

mysql查詢表名匹配只有字母的_MySQL按某些匹配字母查詢表

MySQL查詢是MySQL的核心功能&#xff0c;有時候我們需要查找帶有某些匹配字母的表。下文對該MySQL查詢方式作了詳細的介紹&#xff0c;供您參考。在MySQL中我們可以使用LIKE或者NOT LIKE操作符進行比較。在MySQL中模式默認是不區分大小寫的。查詢示例&#xff0c;student表----…

hdu 1181(Floyed)

變形課 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others)Total Submission(s): 20748 Accepted Submission(s): 7494 Problem Description呃......變形課上Harry碰到了一點小麻煩,因為他并不像Hermione那樣能夠記住所有的咒語而隨意的…

讀書筆記-你不知道的JS上-混入與原型

繼承 mixin混合繼承 function mixin(obj1, obj2) {for (var key in obj2) {//重復不復制if (!(key in obj1)) {obj1[key] obj2[key];}}return obj1;} 這種復制是淺復制&#xff0c;對象或者數組函數等都是同一個引用&#xff0c;改變obj1的會同時影響obj2。 寄生繼承 ... 隱式…

JUnit和Hamcrest:在assertEquals上進行改進

在我的博客文章中&#xff0c;Java越來越接受靜態導入嗎&#xff1f; &#xff0c;我討論了在Java中越來越多地使用靜態導入來使代碼在某些情況下更流暢。 Java 單元測試特別受靜態導入的影響&#xff0c;在此博客文章中&#xff0c;我提供了一個簡單的示例&#xff0c;說明如何…

mysql delete temporary denied_這些錯誤是什么意思?djang中的mysql

我試著運行一個程序&#xff0c;我被給予了一個例子&#xff0c;它就像一個購物網站&#xff0c;使用MySQL數據庫而不是Django提供的原始數據庫&#xff01;我只是想看看有沒有人理解這些錯誤的含義&#xff1f;任何信息都將不勝感激&#xff01;我本可以提供網頁的代碼&#x…

C語言 · 芯片測試

基礎練習 芯片測試 時間限制&#xff1a;1.0s 內存限制&#xff1a;512.0MB問題描述有n&#xff08;2≤n≤20&#xff09;塊芯片&#xff0c;有好有壞&#xff0c;已知好芯片比壞芯片多。每個芯片都能用來測試其他芯片。用好芯片測試其他芯片時&#xff0c;能正確給出被測試…

Animation用法

測試代碼及說明&#xff1a; <!DOCTYPE html> <html lang"en-US"> <head><meta charset"UTF-8"><title>Simple CSS3 Animation</title><style type"text/css">#demo {position: absolute;left: 30%;t…

mysql dese_MySQL 5.6-類似于DENSE_RANK的功能,無需訂購

小編典典對于 MySQL版本<8.0(OP的版本是5.6)&#xff1a;問題陳述看起來需要DENSE_RANK功能groupVarian; 但是事實并非如此。正如 GordonLinoff解釋的那樣 &#xff1a;您似乎希望按它們在數據中出現的順序來枚舉它們。假設您的表名是t(請為您的代碼相應地更改表名和字段名)…

Spring和JSF集成:動態導航

通常&#xff0c;您的JSF應用程序將需要超越基本的靜態導航并開始做出動態導航決策。 例如&#xff0c;您可能想根據用戶的年齡重定向他們。 大多數JSF教程建議通過將命令的action屬性綁定到支持bean來實現動態導航&#xff1a; <h:commandButton action"#{bean.action…

通過富文本改變UITextFieldPlaceholder顏色

1、通過屬性 a、 //文字屬性(一般) NSMutableDictionary *attrs [NSMutableDictionary dictionary]; attrs[NSForegroundColorAttributeName] [UIColor blueColor]; NSAttributedString *placeholderStr [[NSAttributedString alloc] initWithString:"手機號" a…

阻塞/非阻塞/同步/異步方法和多線程的關系?沒有任何關系,倆不挨著

1.阻塞非阻塞異步同步是針對方法說的&#xff0c;是評判一個方法運行狀態的。和多線程完全兩個級別。 2.阻塞非阻塞異步同步是針對方法說的&#xff0c;是評判一個方法運行狀態的。和多線程完全兩個級別。 3.阻塞非阻塞異步同步是針對方法說的&#xff0c;是評判一個方法運行狀…