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

java - what is the best collection for this use case?

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

class ItemUpdateJob {
    int itemId;
    int number;
}

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

existingItemJobInQueue.number += requestedItemJob.number;

所以队列不会开始有数千个相同项目的作业。当作业开始执行时,我需要以某种方式遍历队列,但是在更新作业时,不应更新它(每个项目都应该有自己的锁吗?)。

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

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

在我看来,您似乎需要多个集合的组合。也许是这样的?

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.Queue 看起来很匹配 - 作业的 FIFO 执行顺序和 Map 用于在更新当前等待的作业时进行快速查找。请记住,某些 Queue 实施具有容量限制,显然这需要同步。