以原子方式更新 2 个 Long 值
Atomically update 2 Long values
假设我在 Java 中有以下 class:
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
使用 LongAdder
或 LongAccumulator
来做到这一点吗?
我试过使用它们,但无法弄清楚如何用它们实现复杂的计算。
不,你不能,当然不能用那些。
您可能会考虑做的事情——这将避免 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);
}
假设我在 Java 中有以下 class:
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
使用 LongAdder
或 LongAccumulator
来做到这一点吗?
我试过使用它们,但无法弄清楚如何用它们实现复杂的计算。
不,你不能,当然不能用那些。
您可能会考虑做的事情——这将避免 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);
}