我有以下多線程環境的場景 - 請求來到一個方法,我想避免重複處理併發請求。由於多個類似請求可能正在等待在阻塞狀態下處理。我使用散列表來跟蹤處理的請求,但它會產生內存泄漏,所以應該如何跟蹤處理的請求,並避免處理可能處於阻塞狀態的相同請求。Java多線程 - 避免重複的請求處理
如何檢查任何等待/阻塞的傳入請求不是在當前線程中處理的請求。
我有以下多線程環境的場景 - 請求來到一個方法,我想避免重複處理併發請求。由於多個類似請求可能正在等待在阻塞狀態下處理。我使用散列表來跟蹤處理的請求,但它會產生內存泄漏,所以應該如何跟蹤處理的請求,並避免處理可能處於阻塞狀態的相同請求。Java多線程 - 避免重複的請求處理
如何檢查任何等待/阻塞的傳入請求不是在當前線程中處理的請求。
如果內存泄漏是問題請看WeakHashMap在處理過程中保留你的請求。
另一種解決方案是使用綁定緩存內存...
好吧,我想我有點明白你想要什麼。
您可以使用ConcurrentSkipListSet
作爲隊列。實現你的排隊內容是這樣的:
class Element implements Comparable<Element> {
//To FIFOnize
private static final AtomicLong SEQ = new AtomicLong();
private final long id = SEQ.incrementAndGet();
//Can only be executed once.
private final Semaphore execPermission = new Semaphore(1);
public int compareTo(Element e){
// If element e1 exists on the queue such that
// e.compareTo(e1) == 0, that element will not
// be placed on the queue.
if(this.equals(e)){
return 0;
}else{
//This will enforce FIFO.
this.id > e.id ? 1 : (this.id < e.id ? -1 : 0);
}
}
//implement both equals and hashCode
public boolean tryAcquire(){
return execPermission.tryAcquire();
}
}
現在你的線程應該,
while(!Thread.currentThread().isInterrupted()){
//Iterates from head, therefore simulates FIFO
for(Element e : queue){
if(e.tryAcquire()){
execute(e); //synchronous
queue.remove(e);
}
}
}
您也可以使用此解決方案的阻斷變異(有界的SortedSet,讓工作線程阻塞,如果沒有元素等)。
爲什麼跟蹤HashMap中的請求(或者您可能選擇的任何其他方式)會導致內存泄漏,這是沒有內在原因的。所有這一切都需要一種方法,一旦它們被處理,就可以移除條目。
這可能意味着讓你的請求處理線程:
我不清楚你的意思。你的意思是等同的請求多次出現,但你只想處理這樣的請求一次? – 2010-04-01 09:12:36
是的。可以說請求通過一些密鑰來區分。一個密鑰可能會有多個請求。我只想處理一個。並且其餘的等待請求不應該被處理。當我處理一個請求時,新的請求可能會持續,並且會等待,我需要避免所有相同的密鑰等待請求。 – seawaves 2010-04-01 09:19:23