![](/img/trans.png)
[英]how i can run the onNavigationItemSelected method in background thread
[英]How can I run a background thread that cleans up some elements in list regularly?
我目前正在實施緩存。 我已完成基本實現,如下所示。 我想要做的是運行一個線程,刪除滿足特定條件的條目。
class Cache {
int timeLimit = 10; //how long each entry needs to be kept after accessed(marked)
int maxEntries = 10; //maximum number of Entries
HashSet<String> set = new HashSet<String>();
public void add(Entry t){
....
}
public Entry access(String key){
//mark Entry that it has been used
//Since it has been marked, background thread should remove this entry after timeLimit seconds.
return set.get(key);
}
....
}
我的問題是,我應該如何實現后台線程,以便線程繞過集合中的條目並刪除已marked && (last access time - now)>timeLimit
?
編輯
上面只是代碼的簡化版本,我沒有寫同步語句。
你為什么重新發明輪子? EhCache (以及任何體面的緩存實現)都會為您完成此任務。 也更輕巧 來自Guava的 MapMaker
Cache
可以自動刪除舊條目。
如果你真的想自己實現它,那就不是那么簡單了。
記住同步。 您應該使用ConcurrentHashMap
或synchronized
關鍵字來存儲條目。 這可能真的很棘手。
你必須以某種方式存儲每個條目的最后訪問時間。 每次訪問條目時,都必須更新該時間戳。
想想驅逐政策。 如果緩存中有多個maxEntries
,首先要刪除哪些?
你真的需要一個后台線程嗎?
這是令人驚訝的,但EhCache(企業就緒且經過驗證)不使用后台線程來使舊條目無效)。 相反,它會等到地圖已滿並懶惰地刪除條目。 這看起來是一個很好的權衡,因為線程很昂貴。
如果你有一個后台線程,那么每個緩存還是一個全局? 您是在創建新緩存時啟動新線程還是擁有所有緩存的全局列表? 這比你想象的要難......
一旦你回答了所有這些問題,實現就相當簡單了:每隔一秒左右查看所有條目,如果滿足你已編寫的條件,則刪除條目。
首先,要synchronized
或使用對集合的訪問權限 基於ConcurrentHashSet
ConcurrentHashMap
的Set
如下面的注釋所示。
其次,編寫新線程,並將其實現為無限循環,定期迭代先前的集合並刪除元素。 您應該以在構造函數中使用正確的集合初始化它的方式編寫此類,這樣您就不必擔心“如何訪問正確的集合”。
我不認為你真的需要一個后台線程。 相反,您可以在執行查找之前或之后刪除過期的條目。 這簡化了整個實現,很難區分。
順便說一句:如果使用LinkedHashMap,可以通過覆蓋removeEldestEntry將其用作LRU緩存(有關示例,請參閱其javadoc)
首先,你呈現的代碼是不完整的,因為HashSet
上沒有get(key)
(所以我假設你的意思是某種Map
)並且你的代碼沒有提到任何“標記”。 還有很多方法可以進行緩存,如果不知道要緩存的內容以及原因,很難找出最佳解決方案。
實現緩存時,通常假設數據結構將由多個線程同時訪問。 因此,您需要做的第一件事是使用線程安全的后備數據結構。 HashMap
不是線程安全的,但是ConcurrentHashMap
是。 還有許多其他並發Map
實現,即Guava , Javolution和高級lib 。 除了地圖之外,還有其他方法可以構建緩存,它們的用處取決於您的用例。 無論如何,即使您決定不需要后台線程,而且在嘗試從緩存中檢索過期對象時,也很可能需要使后備數據結構成為線程安全的。 或者讓GC使用SoftReference
刪除條目。
一旦你的高速緩存的內部線程安全,你可以簡單地啟動一個新的(很可能是守護進程)線程,定期掃描/迭代緩存並刪除舊條目。 線程將在循環中執行此操作(直到被中斷,如果您希望能夠再次停止它),然后在每次掃描后休眠一段時間。
但是,您應該考慮構建自己的緩存實現是否值得。 編寫線程安全代碼並不容易,我建議您在嘗試編寫自己的緩存實現之前先研究它。 我可以推薦Java Concurrency in Practice一書。
當然,更簡單的方法是使用現有的緩存實現。 Java-land中有許多選項,都有自己獨特的權衡取舍。
ConcurrentMap
的API。 由於您希望限制緩存中的條目數,因此您可能對對象池而不是緩存感興趣。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.