微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

以原子方式更新2个Long值

如何解决以原子方式更新2个Long值

假设我在Java中有以下课程:

class Record {
  
  String name;
  double count;
  long repeat;
  
  public Record(String name){
    this.name = name;
  }

  public synchronized void update(Record other){
    this.count = (other.count * other.repeat + this.count * this.repeat)/(other.repeat + this.repeat);
    this.repeat = this.repeat + other.repeat;
  }

现在我有一张这样的记录图ConcurrentHashMap<String,Record> recordConcurrentHashMap;

我想创建一个线程安全的正确更新函数

目前,我已经这样做了:

static ConcurrentHashMap<String,Record> recordConcurrentHashMap;

public static void updateRecords(Record other){
    Record record = recordConcurrentHashMap.computeIfAbsent(other.name,Record::new);
    record.update(other);
}

我必须保持update函数同步以实现正确性。

在没有synchronized的情况下可以使用LongAdderLongAccumulator来做到这一点吗?

我尝试使用它们,但无法弄清楚如何使用它们实现复杂的计算。

解决方法

不,您不能,当然不能。

您可能会考虑做的事情–避免使用synchronized –是使Record不变且不可修改,并做类似的事情

class Record {
  final String name;
  final double count;
  final long repeat;

  public Record(String name){
    this.name = name;
  }

  private Record(String name,double count,long repeat) {
    this.name = name; this.count = count; this.repeat = repeat;
  }

  public Record combine(Record other){
    return new Record(
      name,other.count * other.repeat + this.count * this.repeat)
         /(other.repeat + this.repeat),repeat + other.repeat);
  }
}

public static void updateRecords(Record other){
  Record record = recordConcurrentHashMap.merge(
    other.name,other,Record::combine);
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。