Java多线程 - 避免重复请求处理

时间:2010-04-01 08:51:16

标签: java multithreading

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

如何检查任何等待/阻止的传入请求不是当前线程中处理的请求。

3 个答案:

答案 0 :(得分:1)

如果内存泄漏问题,请查看WeakHashMap以便在处理期间保留您的请求。

另一种解决方案是使用内存绑定缓存...

答案 1 :(得分:1)

好的,我想我有点理解你想要的东西。

您可以使用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,如果没有元素等,让工作线程阻塞)。

答案 2 :(得分:1)

没有固有的原因,为什么在HashMap中跟踪请求(或您可能选择的任何其他方式)会导致内存泄漏。所需要的只是一旦条目被处理后就被删除的方式。

这可能意味着让您的请求处理线程:

  • 直接删除条目;
  • 与调度员沟通;或
  • 将请求标记为已处理,因此 调度员可以删除条目。