我有以下多线程环境的场景 - 请求来到一个方法,我想避免重复处理并发请求。由于多个类似请求可能正在等待在阻塞状态下处理。我使用散列表来跟踪处理的请求,但它会产生内存泄漏,所以应该如何跟踪处理的请求,并避免处理可能处于阻塞状态的相同请求。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