我有用例,其中一個隊列持有UploadItem(s)。隊列必須是線程安全的。 UploadItem有一個方法canUpload()。 UploadItems被添加到尾部的隊列中,但peek()和poll()必須返回canUpload()爲true的第一個UploadItem。這可能是頭上的項目或更新的項目。實質上,我希望項目在被準備好上傳之前被忽略,並且我希望隊列返回已準備好的最舊項目。如果輪詢不一定返回第一個項目,那麼ConcurrentLinkedQueue是一個很好的選擇嗎?
爲了解決這個問題,我擴展了一個ConcurrentLinkedQueue,並且我重寫了peek()和poll()。我已經同步了重寫方法,並且正在使用迭代器來檢索第一個有效的項目。
public class UploadQueue extends ConcurrentLinkedQueue<UploadItem> {
public UploadQueue() {}
@Override public synchronized UploadItem peek() {
for (UploadItem item : this) {
if (item.canUpload()) {
return item;
}
}
return null;
}
@Override public synchronized UploadItem poll() {
for (UploadItem item : this) {
if (item.canUpload()) {
remove(item);
return item;
}
}
return null;
}
}
這是一個很好的實現,或者這可以做得更有效嗎?使用迭代器檢索項目是否有不利影響?我不能選擇使用索引和get()的項目,所以看起來我必須使用迭代器。我無法跟蹤內部變量中的項目,因爲它們被外部函數鏈接和更改。
這將在Android上運行,Android仍然使用Java 6.面對Lock-Free Concurrent Linked List in Java和ConcurrentLinkedQueue$Node remains in heap after remove(),是否存在某些Android手機可能仍然存在Java內存泄漏的風險?有誰知道Java是否通常在Android上進行更新/修補(在其主要版本中)?
「這兩個標準並不相互排斥。」同意;-) canUpload()很便宜。它比較單個日期變量。隊列通常不超過100個項目,但如果沒有可用的網絡連接,隊列可能會增加。我可以看到爲什麼你提出了循環法,因爲當網絡在長時間和隊列很長時間後變得可用時,由於每次輪詢()的迭代,性能可能會顯着降低。謝謝你討論這個。 – 2014-12-07 15:36:34
根據你所說的話,我認爲效率不會是一個主要問題。如果是,那麼我的第一個建議(當項目變成「可上傳的」時加入隊列)應該接近最優。 – 2014-12-07 22:18:16