【发布时间】:2018-02-28 16:34:06
【问题描述】:
我有 N 个添加值的线程和一个删除线程。我正在考虑如何同步添加到现有值列表和删除列表的最佳方式。
我猜以下情况是可能的:
thread 1 checked condition containsKey, and entered in else block
thread 2 removed the value
thread 1 try to add value to existing list, and get returns null
我认为我可以使用的唯一方法是按地图值同步,在我们的例子中是添加和删除时的列表
private ConcurrentSkipListMap<LocalDateTime, List<Task>> tasks = new ConcurrentSkipListMap<>();
//Thread1,3...N
public void add(LocalDateTime time, Task task) {
if (!tasks.containsKey(time)) {
tasks.computeIfAbsent(time, k -> createValue(task));
} else {
//potentially should be synced
tasks.get(time).add(task);
}
}
private List<Task> createValue(Task val) {
return new ArrayList<>(Arrays.asList(val));
}
//thread 2
public void remove()
while(true){
Map.Entry<LocalDateTime, List<Task>> keyVal = tasks.firstEntry();
if (isSomeCondition(keyVal)) {
tasks.remove(keyVal.getKey());
for (Task t : keyVal.getValue()) {
//do task processing
}
}
}
}
【问题讨论】:
-
您需要
ConcurrentSkipListMap吗?ConcurrentHashMap为compute和computeIfAbsent等操作提供原子性保证,这在这里可能非常有用。 -
@shmosel 我猜是因为我想存储按 LocalDateTime 排序的记录
-
@shmosel 与 CSLM 相比,我不清楚 CHM 保证在这里能真正帮助您。
-
我当然希望我错了,但我知道没有任何东西可以满足您的需求,没有外部/额外的同步。
标签: java multithreading java-8 java.util.concurrent