0

我正在尝试为从外部数据源获取的数据实现缓存。我试图弄清楚我是否可以一起避免锁定并使用时间戳来确保过时的数据永远不会插入缓存中。是否已经为此开发了一种机制?让我举个例子:

    // Reader thread does
   1 Data readData(id) {
   2       Data data = cache.get(id);
   3       if(data == null)
   4           data = extDataSrc.readData(id);
   5       cache.put(id, data);   
   6       return data;    }

    // Writer thread does
   7 void updateData(id, Data data) {
   8        extDataSrc.updateData(id, data);
   9        cache.remove(id); 
   10 }

所以现在没有锁,当缓存中不存在 id 时,reader 可能会调用 extDataSrc。如果同时 writer 更新相同的 id,则可能在 writer 提交之前,reader 读取过时的数据并延迟从 extDataSrc 调用返回。同时 writer 执行 cache.remove(id) (缓存中没有数据,因此不会删除任何内容)并返回。Reader 然后执行 cache.put(id)。我在想这可以通过使用时间戳来避免,这样当阅读器检查缓存时,它会保存一个时间戳 TR1(在第 2 行之后:检查缓存的 id 时间)。Writer 在执行 remove 后保存 TW1(第 9 行之后:更新时间)。读取器在执行第 4 行后,再次保存 TR2(第 4 行之后:读取完成且缓存更新即将开始时)。这里如果 TR2 > TW1,它会跳过缓存。

所以,TR1 = 100,TW1 = 105,TR2 = 110 => 跳过 cache.put。

有什么意义吗?

4

2 回答 2

1

看一下:

于 2013-11-06T15:06:29.017 回答
0

我建议在执行时将临时同步对象放入缓存extDataSrc.readData(id)中。首先,如果两个读取线程请求同一个项目,第二个线程不需要发出多余的请求,而只是等待第一个发出的请求。其次,当作者看到请求正在进行时,它可以简单地将其数据放入缓存中并提供给读者。完成readData后,它必须检查请求是否已被写入者满足(缓存项是数据,而不是临时对象)并简单地丢弃来自extDataSrc.

而不是使用时间戳,我会在数据对象中使用版本号——即使有多个进程写入同一个extDataSrc.

于 2013-11-06T16:51:25.530 回答