如何使用ReadWriteLock?

Edw*_*ndt 5 java caching map

我是以下情况.

在Web应用程序启动时,我需要加载一个Map,然后由多个传入线程使用.也就是说,请求进入并且Map用于查明它是否包含特定键,如果是,则检索值(对象)并将其与另一个对象相关联.

现在,有时地图的内容会发生变化.我不想重新启动我的应用程序来重新加载新的情况.相反,我想动态地这样做.

但是,在Map重新加载(删除所有项目并用新项目替换它们)时,该Map上的并发读取请求仍然到达.

我该怎么做才能防止所有读取线程在重新加载时访问该Map?我怎样才能以最高性能的方式做到这一点,因为我只需要在Map重新加载时只需偶尔发生(每x周一次)?

如果以上不是一个选项(阻塞),我怎样才能确保在重新加载我的读取请求时不会遇到意外的异常(因为某个键不再存在,或者某个值不再存在或正在重新加载)?

我得到了ReadWriteLock可能帮助我的建议.你能否为我提供一个关于如何将这个ReadWriteLock与我的读者和作者一起使用的例子?

谢谢,
E

KLE*_*KLE 6

我建议按如下方式处理:

  1. 您的地图可以在中心位置访问(可以是Spring单例,静态...).
  2. 在开始重新加载时,让实例保持原样,在另一个Map实例中工作.
  3. 填充新地图时,将旧地图替换为新地图(这是原子操作).

示例代码:

    static volatile Map<U, V> map = ....;

    // **************************

    Map<U, V> tempMap = new ...;
    load(tempMap);
    map = tempMap;
Run Code Online (Sandbox Code Playgroud)

并发效果:

  • volatile 帮助将变量的可见性提供给其他线程.
  • 在重新加载地图时,所有其他线程都会看到旧值不受干扰,因此它们不会受到任何惩罚.
  • 任何在更改映射之前检索映射的线程都将使用旧值.
    • 它可以要求多个获取相同的旧地图实例,这对于数据一致性很好(不是从旧地图加载第一个值,而是从较新的地图加载其他值).
    • 它将使用旧地图完成处理其请求,但下一个请求将再次询问地图,并将接收更新的值.