本文介紹了基于時間的線程安全優先級隊列的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學習吧!
問題描述
我需要一些類似隊列的數據結構來執行以下任務:
-
有些線程添加了附加延遲值的數據項(例如秒),例如
queue.add(data, delay)
。既可以有不同的延遲,也可以有相同的延遲,隊列應充當優先隊列:延遲越小的項越接近末尾(出隊速度更快)
排隊項每秒鐘
delay
應減1,直到達到0(然后保持不變為0)在
delay
為0
的項目中,出列順序就是它們的插入順序(雖然到達0
的順序更好)一些客戶端線程系統地從該隊列中獲取元素,并且它只提供
delay = 0
元素。如果不存在,則它將阻塞或引發。
因此,我想要一些隊列的功能+一點調度、線程安全。我懷疑,在某些情況下,這類事情應該是一項相當常規的任務。
我的問題:對于此類任務,是否有針對java
或scala
的生產就緒解決方案?我不想再發明另一輛自行車了。
編輯:似乎在Java標準庫中確實有這樣的東西:DelayQueue
,在回答之前先看一看。
推薦答案
您可以使用應作為輸入Comparable
對象的PriorityQueue
。
您應該基于Timestamp
字段比較這些對象(越小越好);正如@Henry已經提到的,存儲Timestamp
比存儲delay
更好。這非常容易實現;只需存儲currentTime + delay
。
然后,當客戶端請求head元素時,您需要創建一個synchronized
方法,該方法執行以下操作:
首先peek()
檢查head元素是否有timestamp < currentTime
如果是,poll()
這個元素,否則拋出。
第二個解決方案(移植自我的評論):
實際上,可以添加一個ScheduledThreadPoolExecutor作為中間層;
現在您不需要Timestamp
,只需將delay
提供給Executor。
當每個runnable/callable
執行時,相應的對象被添加到另一個正常的FIFO隊列,在那里它將立即可用于輪詢;
您的客戶端現在可以輪詢第二個FIFO隊列中的元素。
這篇關于基于時間的線程安全優先級隊列的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,