2 回答
TA贡献2003条经验 获得超2个赞
我不确定您在第二个示例中要做什么,您有 (1) 一个不必要的构造函数和字段,以及 (2) 一个不必要的安全映射(没有更多信息,我担心这是无用的)。您的第一个解决方案是两者中最“正确”的,除非您想修改secId
(在这种情况下,您需要在Security
类中进行额外的同步)。
我认为最理想的解决方案是ConcurrentHashMap
在这种情况下使用并取消锁定。
TA贡献1895条经验 获得超3个赞
您遇到了简单并发结构的问题,即更新结构需要您锁定整个结构,无论使用的是什么密钥。这显然会损害并发性。您的缓存必须可供所有线程访问,因此锁定它会阻止所有其他尝试访问该结构的线程。
这样做的原因是添加或删除条目会导致映射中的内部结构被修改,从而影响其他键。所以你必须锁定整个结构。
您的第一个解决方案将起作用,但与将地图包装在 a 中SynchronizedMap
(可能更糟)相同。
您的第二个解决方案有很多错误,但通常它不会起作用,因为它不会锁定地图。
有两种前进方式:
如果您事先知道所有证券是什么,您可以预先构建包含所有已知密钥的缓存。我相信您然后可以获取和放置并且您不需要同步,因为您只会覆盖现有的地图条目。如果您真的想确定,您可以在地图中创建一个 Price 类作为价值项目,其中包含您可以修改的价格,然后使用 Price 对象预加载缓存,然后修改 Price 对象中的价格字段。您将永远不必在初始加载后执行 get 和 put 操作。
如果您事先不知道所有键或者不想预加载缓存,请使用
ConcurrentHashMap
.ConcurrentHashMap
确实同步,但它在内部创建了多个段,并有巧妙的策略来分割一组键,这样它就不必锁定整个地图,只需要锁定一个段。这意味着很有可能避免缓存中的争用。手动条目指出读取通常不会阻塞,并且可以向构造函数指定并发值以控制预期的并发线程数。
添加回答
举报