如果在使用时 ConcurrentMap 中不存在新元素,如何添加新元素
How to add a new element in case it does not exist in a ConcurrentMap while are using
我正在使用线程进行 Java 开发,事实上我没有太多想法。它比我想象的要复杂。
问题是我必须将几个对象组合在一个ConcurrentMap 中,如果该对象不在ConcurrentMap 中必须添加它,否则修改它。
对于修改数据的部分我没有问题,但是当我想更新时我得到一个“递归更新”错误,我不知道我还能对 modify/add 我的 ConcurrentMap 做些什么并使其成为线程安全的。
private final ConcurrentMap<String, Person> myData= new ConcurrentHashMap<>();
private void processMyData(){
myData.compute(String, (key, person) -> {
if (person== null) {
myData.putIfAbsent(key, new Person("Antonio", 0, false));
} else {
//Update data, this part its ok!
person.setConnectedHours(person.getConnectedHours() + 1000);
}
return person;
});
}
如果密钥不存在,您只需创建一个新的 person
对象并 return 它。 ConcurrentMap#Compute
将确保整个调用是原子的。
如果在 compute
中不存在 key 时调用 putIfAbsent
,则会导致无限循环。 (无限循环发生在 ConcurrentHashMap#putVal
方法中)。
myData.compute("A", (key, person) -> {
if (person== null) {
person = new Person();
} else {
//Update data, this part its ok!
}
return person;
});
参见 ConcurrentMap#compute
JDK 文档:
Attempts to compute a mapping for the specified key and its current mapped value (or null if there is no current mapping). For example, to either create or append a String msg to a value mapping:
map.compute(key, (k, v) -> (v == null) ? msg : v.concat(msg))
我昨晚找到了解决方案,但我忘了回答这张工单。
我意识到在一个新项目中做了一些非常简单的测试,当我应用一个简单的 lambda ex: (k,val) -> v == null 时,我可以做一个 put ? “新文本”:“修改”
然后,我只是看到我在生成新对象时没有执行 return,所以它不是实例。
初学者的错误呵呵,但希望对和我有同样错误的人有所帮助:)
此致!
private final ConcurrentMap<String, Person> myData= new ConcurrentHashMap<>();
private void processMyData(){
myData.compute(String, (key, person) -> {
if (person== null) {
return new Person("Antonio", 0, false);
} else {
//Update data, this part its ok!
person.setConnectedHours(person.getConnectedHours() + 1000);
return person;
}
});
}
我正在使用线程进行 Java 开发,事实上我没有太多想法。它比我想象的要复杂。
问题是我必须将几个对象组合在一个ConcurrentMap 中,如果该对象不在ConcurrentMap 中必须添加它,否则修改它。
对于修改数据的部分我没有问题,但是当我想更新时我得到一个“递归更新”错误,我不知道我还能对 modify/add 我的 ConcurrentMap 做些什么并使其成为线程安全的。
private final ConcurrentMap<String, Person> myData= new ConcurrentHashMap<>();
private void processMyData(){
myData.compute(String, (key, person) -> {
if (person== null) {
myData.putIfAbsent(key, new Person("Antonio", 0, false));
} else {
//Update data, this part its ok!
person.setConnectedHours(person.getConnectedHours() + 1000);
}
return person;
});
}
如果密钥不存在,您只需创建一个新的 person
对象并 return 它。 ConcurrentMap#Compute
将确保整个调用是原子的。
如果在 compute
中不存在 key 时调用 putIfAbsent
,则会导致无限循环。 (无限循环发生在 ConcurrentHashMap#putVal
方法中)。
myData.compute("A", (key, person) -> {
if (person== null) {
person = new Person();
} else {
//Update data, this part its ok!
}
return person;
});
参见 ConcurrentMap#compute
JDK 文档:
Attempts to compute a mapping for the specified key and its current mapped value (or null if there is no current mapping). For example, to either create or append a String msg to a value mapping: map.compute(key, (k, v) -> (v == null) ? msg : v.concat(msg))
我昨晚找到了解决方案,但我忘了回答这张工单。
我意识到在一个新项目中做了一些非常简单的测试,当我应用一个简单的 lambda ex: (k,val) -> v == null 时,我可以做一个 put ? “新文本”:“修改”
然后,我只是看到我在生成新对象时没有执行 return,所以它不是实例。
初学者的错误呵呵,但希望对和我有同样错误的人有所帮助:)
此致!
private final ConcurrentMap<String, Person> myData= new ConcurrentHashMap<>();
private void processMyData(){
myData.compute(String, (key, person) -> {
if (person== null) {
return new Person("Antonio", 0, false);
} else {
//Update data, this part its ok!
person.setConnectedHours(person.getConnectedHours() + 1000);
return person;
}
});
}