当前位置: 首页 > 知识库问答 >
问题:

java-这个用例的最佳集合是什么?

刘向阳
2023-03-14

我有一个密集更新的列表,所以我将它们分组在一起,并在单个线程中作为批处理作业执行它们。其他线程可以随时发送更新。

class ItemUpdateJob {
    int itemId;
    int number;
}

当调度要排队更新的作业时,我想要一个集合,如果作业已经存在,我可以在其中修改作业(假设itemId为键)。在这个例子中:

existingItemJobInQueue.number += requestedItemJob.number;

因此,队列不会开始为同一项提供数千个作业。当作业开始执行时,我需要以某种方式在队列中循环,但是在更新作业时,它不应该被更新(每个项目都应该有自己的锁吗?)。

for (ItemUpdateJob job : jobQueue) {
    updateItem(job);
}

更新作业后,应立即将其从队列中删除。最好的方法是什么?目前,我正在考虑使用一个HashMap,将项id作为键,然后每个项都有一个锁,可以防止在更新项时修改现有作业。不过,这将导致在等待更新完成时暂停(释放锁)。

共有1个答案

洪照
2023-03-14

在我看来,似乎你需要一个以上的集合组合。也许是这样的?

public class JobHandler {

  //jobs still in the queue, map for a quick lookup
  private final Map<Integer, ItemUpdateJob> waitingJobs;
  //jobs still waiting to be run
  private final Queue<ItemUpdateJob> jobQueue;

  public JobHandler(Collection<ItemUpdateJob> jobs) {
    this.waitingJobs = new HashMap<>();
    this.jobQueue = new LinkedList<>();
    this.init(jobs);
  }
  
  private void init(Collection<ItemUpdateJob> jobs) {
    for (ItemUpdateJob job : jobs) {
      this.waitingJobs.put(job.itemId, job);
      this.jobQueue.add(job);
    }
  }

  public ItemUpdateJob getNextJobToRun() {
    ItemUpdateJob nextJob = this.jobQueue.poll();
    if (nextJob != null) {
      this.waitingJobs.remove(nextJob.itemId);
    }
    return nextJob;
  }

  public void addJob(ItemUpdateJob job) {
    this.waitingJobs.put(job.itemId, job);
    this.jobQueue.add(job);
  }

  public boolean updateJob(ItemUpdateJob updateJob) {
    if (this.waitingJobs.containsKey(updateJob.itemId)) {
      //job is currently waiting for execution, so update it
      this.waitingJobs.get(updateJob.itemId).number += updateJob.number;
      return true;
    } else {
      //job is currently being run, or no such job at all
      //so adding it at the end of the queue to wait for it's turn
      this.addJob(updateJob);
      return false;
    }
  }
}

java.util.队列看起来像是一个很好的匹配-FIFO执行顺序的作业和一个Map在更新当前等待的作业时快速查找。请记住,某些Queue实现有容量限制,显然这需要同步。

 类似资料:
  • 问题内容: 我想过滤java.util.Collection基于谓词的。 问题答案: Java 8(2014)在一行代码中使用流和lambda解决了此问题: 这是一个教程。 使用修改收集到位。(注意:在这种情况下,谓词将删除满足该谓词的对象): 允许过滤集合而无需编写循环或内部类: 你能想象一些更具可读性的东西吗?

  • Java宣布一个集合为最终集合意味着什么?是不能再添加更多元素了吗?是已经存在的元素不能更改吗?是别的什么吗?

  • 我正在使用Neo4j进行社交网络分析,我想知道是否需要使用Spring Data。节点的所有属性都是由客户端动态提供的,在Spring数据中,Neo4j节点总是映射到一个对象,这意味着节点的模式是不可变的。那么,只有当每个节点的模式不可变时,Spring数据才能使用,还是我错过了什么? 我已经在Spring环境中工作了。

  • 主要内容:1 什么是Java集合,2 Java集合层次结构,3 Java Collection接口的方法,4 Iterator接口,5 Iterable接口,6 Collection接口,7 List接口,6 ArrayList,7 LinkedList,8 Vector,9 Stack,10 Queue接口,11 PriorityQueue,12 Deque接口,13 ArrayDeque,14 Set接口,15 HashSet,16 LinkedHashSet,17 SortedSet接口,

  • 问题内容: 我们有两个PHP5对象,并希望将其中一个的内容合并到第二个中。它们之间没有子类的概念,因此以下主题中描述的解决方案不适用。 备注: 这些是对象,而不是类。 对象包含很多字段,所以 foreach 会很慢。 到目前为止,我们考虑将对象A和B转换为数组,然后在重新转换为对象之前使用 array_merge() 合并它们,但是我们不能为此感到骄傲。 问题答案: 如果您的对象仅包含字段(没有方

  • 问题内容: 我有一套清单: 我要s1∩s2∩s3 … 我可以编写一个函数来执行一系列成对的操作,等等。 有没有推荐,更好或内置的方法? 问题答案: 从python版本2.6开始,您可以对使用多个参数,例如 如果这些集合在列表中,则表示为: 这里是列表扩展 请注意,是 不是 一个静态的方法,但这种使用功能符号应用第一套交叉口列表的其余部分。因此,如果参数列表为空,则将失败。