public void updatePrice(Price update){
sendPriceUpdate(update); //takes a long time
}
我想構造一個類,它將執行上述操作,除了sendPriceUpdate調用仍在運行時它將等待並排隊等待更新。一旦通話返回,它將發送上次更新(並放棄其他更新)。即等待發送呼叫返回,然後發送最後一次掛起的價格更新。異步隊列 - 只處理最後一條消息
請告訴我合適的數據結構使用?
public void updatePrice(Price update){
sendPriceUpdate(update); //takes a long time
}
我想構造一個類,它將執行上述操作,除了sendPriceUpdate調用仍在運行時它將等待並排隊等待更新。一旦通話返回,它將發送上次更新(並放棄其他更新)。即等待發送呼叫返回,然後發送最後一次掛起的價格更新。異步隊列 - 只處理最後一條消息
請告訴我合適的數據結構使用?
最好的解決方案是更新已經知道這一點,只得到「增量」的數據,也就是說,改變了數據或唯一的區別。如果這是不可能的,那麼你別無選擇,只能回滾最新的更新。爲此,您需要存儲以前的更新,以便撤消它並推送新的更新。像這樣的東西應該工作:
public class Updater
{
private static Price prevUpdate = null;
public static synchronized void updatePrice(Price update)
{
if (prevUpdate != null)
{
rollbackUpdate(prevUpdate);
}
sendPriceUpdate(update); //takes a long time
prevUpdate = update;
}
}
我已經改變了這static
,因爲我不認爲你需要實例這個類的一個對象。看起來像一個靜態的服務給我。如果我錯了(例如不同的線程想要使用不同的更新程序,並因此跟蹤不同的更新),請更改它。
這是線程安全的,但如果sendPriceUpdate()
需要很長時間,它可以鎖定updatePrice()
方法上的很多線程。此外,這不考慮任何異常被拋出,你應該考慮到這一點。
正如我在評論中說,恕我直言,這是一個(非常?)不好解決,但它是唯一一個,如果你不知道這是最後一個或最後一個抵達。重新設計的軟件可能會解決這種情況,或者在更高層次上解決它(在調用updatePrice()
之前)
這不會起作用,因爲它會處理所有的價格更新...我只想處理最新的價格更新。 –
咦?你說:「我想構建一個類,它將執行上述操作,除了sendPriceUpdate調用仍在運行時,它將等待並排隊等待更新」。排隊不僅僅處理最後一個。請澄清你自己。 – m0skit0
爲什麼你引用我,甚至不包括整個段落?下一句話明確表示放棄除最後更新之外的所有內容。 –
我建議您使用主動對象模式 - 您應該將隊列(AKA激活隊列或操作隊列)你的對象。我將首先解釋如何在不丟棄的情況下解決問題,然後解釋我應如何處理丟棄問題。 其主要思想是:
A.你的對象有一個隊列的領域 - 比方說,一個泛型類型隊列的(與PriceOperation通用參數)
B. PriceOperation將舉行一個方法對象(java中。 lang.reflect.method),調用的目標對象-let的PriceManager(具有updatePrice方法)和參數(假設爲更新它應該是Price)
C. sendPriceUpdate將排隊和PriceOperation的對象「更新」的方法,對象(假設價格有這樣的一種方法),或方法,你會在同步調用
D.與該物體相關的Wi線程的情況下,已啓動LL等待隊列,當隊列不爲空,它會出隊PriceOperation對象,並調用目標對象的方法(這是否如果是PriceManager或別的東西)的有關參數(價格對象)
E.通過這種方式,您將能夠保留待處理更新的隊列,並且仍然與您的PriceManager異步工作
F.我剛剛注意到您有意丟棄上次更新 - 如果是這種情況,那麼您應該優先使用優先級隊列,而不是隊列,並根據時間戳上的優先級排序,以最近創建的PriceOperation進行處理。您需要在過程器(PriceManager)和使用者(線程)之間同步這個隊列。
您標記爲「排隊」,我想你已經知道合適的數據結構。 –
事情是我不知道如果一個隊列是正確的,因爲我只想要最後更新..真的需要在隊列中存儲多個項目。 –