我正在同时使用WeakHashMap。 我想基于整数参数实现细粒度锁定;如果线程A需要修改由整数a
标识的资源,而线程B也对由整数b
标识的资源进行相同的操作,则它们不需要同步。但是,如果有两个线程使用同一个资源,例如线程C也在使用由整数a
标识的资源,则当然线程A和C需要在同一个锁上同步。
当没有更多需要ID为X的资源的线程时,则可以删除Map中用于键=X的锁。但是,在此时可能会有另一个线程进入并尝试使用Map中ID=X的锁,因此我们需要在添加/删除锁时进行全局同步。(这将是每个线程都必须同步的唯一地方,无论整数参数如何)。但��,线程无法知道何时删除锁,因为它不知道它是否是最后一个使用锁的线程。
这就是为什么我正在使用WeakHashMap的原因:当ID不再使用时,当GC需要时,可以删除键值对。
为了确保对已存在条目的键具有强引用,并且正是形成映射的键的对象引用,我需要迭代映射的keySet:
synchronized (mrLocks){
// ... do other stuff
for (Integer entryKey : mrLocks.keySet()) {
if (entryKey.equals(id)) {
key = entryKey;
break;
}
}
// if key==null, no thread has a strong reference to the Integer
// key, so no thread is doing work on resource with id, so we can
// add a mapping (new Integer(id) => new ReentrantLock()) here as
// we are in a synchronized block. We must keep a strong reference
// to the newly created Integer, because otherwise the id-lock mapping
// may already have been removed by the time we start using it, and
// then other threads will not use the same Lock object for this
// resource
}
现在,在迭代过程中,Map的内容可以更改吗?我认为不行,因为通过调用mrLocks.keySet()
,我为迭代范围内的所有键创建了强引用。这正确吗?