我正在使用Map构建一个小缓存,该缓存包含一些数据库查询的缓存结果。假设以线程安全的方式填充此缓存。我的问题是关于此缓存中的条目,结果类型的对象。
考虑以下情况:
线程1从缓存中读取并获取一些Result对象,称之为R. 线程2希望同一个对象R被杀死,因此它会调用缓存来终止对象R。
看到两个线程如何仅保持对对象R的引用,对于线程1,对象R有可能突然变为空,因为线程2已经调用它来杀死它。
我该如何避免这种情况?当线程从缓存中读取时,我是否应该对对象R进行深层复制,这样即使线程2杀死缓存,线程1仍然可以完成它正在做的事情而没有问题?或者还有另一种方法吗?我对线程和并发的经验不是最大的,所以要温柔......
答案 0 :(得分:2)
是 - 通常将结果视为值对象。线程2会将其从缓存中删除/或用更新的值覆盖缓存,但通常不会损坏/破坏R的内部状态。
线程2“将null放入缓存”或“将新值放入缓存”本身不会影响使用R的任何其他引用或线程。除非你特意破坏它,否则R中的任何东西都会破坏。从缓存中请求对象的代码将不再被赋予对该R的特定引用。
指针/或引用将改变或设置为null,状态& R本身的领域不会。
这假设R不包含需要释放的资源..
如果R 需要保留资源(这不是通常的情况),那么您可能需要添加使用中的计数器并计算两者都在使用中通过在缓存中保存正在被客户端代码使用,这样只有当计数器减少到零时才释放R的资源。
但这是一个不寻常的要求。
答案 1 :(得分:0)
如果您的“kill”操作修改了Result的内部,那么您可能会遇到此问题。 如果它不是,那么已经从缓存中接收它的线程的引用不能变为null。从地图中删除对象不会使引用为空。