首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java并发-数据结构,以避免对具有相同ID的对象进行并发修改

Java并发-数据结构,以避免对具有相同ID的对象进行并发修改
EN

Stack Overflow用户
提问于 2019-08-02 13:06:09
回答 2查看 114关注 0票数 0

对于以下情况,正确的结构是什么?

假设我们有一个股票系统(域并不重要,只是一个例子),而且每个操作都很慢(例如,与外部系统联系)。

  • 它处理50个仓库。
  • 我可以把股票从一个WH转移到另一个WH。
  • 我想保证最后的股票是正确的。

我想的是,我可以以并行的方式处理不影响相同WH的请求。例如:

  1. 将20个项目从WH1移至3的请求
  2. 将15项从2项移动到5项的请求(可以与前一项并行处理)
  3. 请求将5项从3项移至6项(应等待第一个请求完成后再继续)。

我正在考虑一个线程安全映射,其中包含了我目前正在处理的仓库的所有ids。

还有什么更好的吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-08-02 15:40:58

我建议为每个lock对象引入一个Warehouse变量以及一个唯一的整数。您可以使用AtomicInteger来确保每个创建的仓库都有其唯一的编号。

代码语言:javascript
复制
public class Warehouse {
    private static final AtomicInteger numberProvider = new AtomicInteger(0);
    private final int number;
    private final Lock lock = new ReentrantLock();
    // ...
    public Warehouse(...) {
        this.number = numberProvider.incrementAndGet();
        ...
    }
    // ... (getter for number and lock and other methods)
}

这样,您可以始终以“正确”顺序锁定两个仓库(例如,首先锁定较低的数字,然后锁定较高的;向后方向解锁)。这将保证您不会遇到死锁。

代码语言:javascript
复制
public void moveStock(Warehouse from, Warehouse to, int nof) {
    List<Lock> locks = Stream.of(from, to)
        .sorted(Comparator.comparingInt(Warehouse::getNumber))
        .map(Warehouse::getLock)
        .collect(Collectors.toList());

    for(int i=0;i<locks.size();++i) {
        locks.get(i).lock();
    }
    try {
        from.substractStock(nof);
        to.addStock(nof);
    } finally {
        for(int i=locks.size()-1;i>=0;i--) {
            locks.get(i).unlock();
        }
    }
}
票数 3
EN

Stack Overflow用户

发布于 2019-08-02 16:21:50

集合将是您正在寻找的数据结构。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57327126

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档