0

我正在使用 Map 构建一个小型缓存,其中包含一些数据库查询的缓存结果。假设这个缓存是以线程安全的方式填充的。我的问题是关于此缓存中的条目,即 Result 类型的对象。

考虑以下场景:

线程 1 从缓存中读取并获取一些 Result 对象,将其称为 R。线程 2 想要相同的对象 R 被杀死,因此它调用缓存来杀死对象 R。

看到两个线程如何只持有对对象 R 的引用,由于线程 2 已发出调用以杀死它,因此对象 R 可能突然为线程 1 变为空。

我该如何避免这种情况?当线程从缓存中读取时,我是否应该制作对象 R 的深层副本,以便即使线程 2 杀死缓存,线程 1 仍然能够完成它正在做的事情而不会出现问题?或者有另一种方法吗?我在线程和并发方面的经验并不是最大的,所以要温柔......

4

2 回答 2

2

是的——通常您将 Result 视为一个值对象。线程 2 会将其从缓存中删除/或用更新的值覆盖缓存,但通常不会损坏/破坏R的内部状态。

线程 2“将 null 放入缓存”或“将新值放入缓存”本身不会影响使用 R 的任何其他引用或线程。R 中的任何内容都不会破​​坏,除非您专门破坏它。代码请求缓存中的对象将不再获得对 R 的特定引用。

指针/或引用将更改或设置为 null,R 本身的状态和字段不会。

这假设 R 不持有需要释放的资源。

如果 R确实需要保存资源,这不是通常的情况,那么您可能需要添加一个正在使用的计数器,并通过保存在缓存中来计算正在使用和被客户端代码使用,这样 R 的仅当计数器减为零时才释放资源。

但这将是一个不寻常的要求。

于 2013-10-17T09:49:12.523 回答
0

如果您的“kill”操作修改了 Result 的内部结构,那么您可能会遇到这个问题。如果不是,则已从缓存中接收到它的线程的引用不能变为空。从地图中删除对象不会使引用为空。

于 2013-10-17T09:54:58.477 回答