Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java多线程-避免重复的请求处理_Java_Multithreading - Fatal编程技术网

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

Java多线程-避免重复的请求处理,java,multithreading,Java,Multithreading,我有以下多线程环境场景-请求将到达一个方法,我希望避免并发请求的重复处理。因为多个类似的请求可能正在等待以阻止状态处理。我使用hashtable跟踪已处理的请求,但它会造成内存泄漏,因此应该如何跟踪已处理的请求并避免可能处于阻塞状态的待处理请求 如何检查任何等待/阻止的传入请求是否不是当前线程中处理的请求。如果内存泄漏是问题所在,请查看以在处理过程中保留您的请求 另一个解决方案是使用内存绑定的缓存…好的,我想我有点理解你想要什么 您可以使用ConcurrentSkipListSet作为队列。实现

我有以下多线程环境场景-请求将到达一个方法,我希望避免并发请求的重复处理。因为多个类似的请求可能正在等待以阻止状态处理。我使用hashtable跟踪已处理的请求,但它会造成内存泄漏,因此应该如何跟踪已处理的请求并避免可能处于阻塞状态的待处理请求


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

如果内存泄漏是问题所在,请查看以在处理过程中保留您的请求


另一个解决方案是使用内存绑定的缓存…

好的,我想我有点理解你想要什么

您可以使用
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();
      }
 }

您还可以使用此解决方案的阻塞变体(有一个有界SortedSet,如果没有元素等,则让工作线程阻塞)。

没有内在的原因说明在HashMap(或您可能选择的任何其他方式)中跟踪请求会导致内存泄漏。所需要的只是一种在处理完条目后将其删除的方法

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

  • 直接删除条目
  • 向调度员反馈信息;或
  • 将请求标记为已处理,以便 调度器可以删除这些条目

我想到了这一点,但有没有不使用任何数据结构的方法可以做到这一点。通过以某种方式构造锁检查和条件检查,我们永远不知道weakhashmap的条目何时会被删除,如果它在处理所有被阻止的请求之前被删除,那么将发生重复的请求处理。我不清楚你的意思。你的意思是说相同的请求会多次出现,但你只想处理这样的请求一次吗?是的。假设请求由某个键区分。一个密钥可能会有多个请求。我只想处理一个。其余的等待请求不应该被处理。当我处理一个请求时,新的请求可能会不断出现并等待,我需要避免所有相同的密钥等待请求。在什么情况下,我应该清理hashmap,我如何知道没有与已处理的线程具有相同请求的等待线程。@seaves:当没有具有相同请求的等待线程时。当dispatcher收到一个已经有线程在运行的请求时,您将使处理该请求的线程等待,对吗?因此,您的调度程序已经有一组请求、一组正在运行的线程和一组正在等待的线程。(小写“set”-通用数学术语,而不是任何特定的数据结构)。因此,当您的调度程序发现正在运行的请求X线程已完成时,它会检查是否有其他线程正在等待处理X,并将其删除或启动其中一个等待程序。
 while(!Thread.currentThread().isInterrupted()){
     //Iterates from head, therefore simulates FIFO
     for(Element e : queue){
          if(e.tryAcquire()){
               execute(e); //synchronous
               queue.remove(e);
          }
     }
 }