【发布时间】:2011-10-26 17:19:58
【问题描述】:
我在我的函数doMapOperation 中有一个名为synchronizedMap 的同步列表。在这个函数中,我需要从地图中添加/删除项目并对这些对象执行昂贵的操作。我知道我不想在同步块中调用昂贵的操作,但我不知道在执行这些操作时如何确保地图处于一致状态。这样做的正确方法是什么?
这是我的初始布局,我确信这是错误的,因为您想避免在同步块中调用昂贵的操作:
public void doMapOperation(Object key1, Object key2) {
synchronized (synchronizedMap) {
// Remove key1 if it exists.
if (synchronizedMap.containsKey(key1)) {
Object value = synchronizedMap.get(key1);
value.doExpensiveOperation(); // Shouldn't be in synchronized block.
synchronizedMap.remove(key1);
}
// Add key2 if necessary.
Object value = synchronizedMap.get(key2);
if (value == null) {
Object value = new Object();
synchronizedMap.put(key2, value);
}
value.doOtherExpensiveOperation(); // Shouldn't be in synchronized block.
} // End of synchronization.
}
我想作为这个问题的延续,您将如何循环执行此操作?
public void doMapOperation(Object... keys) {
synchronized (synchronizedMap) {
// Loop through keys and remove them.
for (Object key : keys) {
// Check if map has key, remove if key exists, add if key doesn't.
if (synchronizedMap.containsKey(key)) {
Object value = synchronizedMap.get(key);
value.doExpensiveOperation(); // Shouldn't be here.
synchronizedMap.remove(key);
} else {
Object value = new Object();
value.doAnotherExpensiveOperation(); // Shouldn't here.
synchronizedMap.put(key, value);
}
}
} // End of synchronization block.
}
感谢您的帮助。
【问题讨论】:
-
这里没有足够的信息来知道在缓慢的操作过程中是否可以放弃锁。关键问题是是否所有这些工作都必须以原子方式发生在其他线程上?如果不是,哪些操作应该是原子的?操作是否必须在整个地图上以原子方式发生?换句话说,如果你能确保对单个键的操作是原子的呢?
标签: java collections synchronization