java—写入concurrenthashmap是否立即可用于所有后续servlet请求?

holgip5t  于 2021-07-08  发布在  Java
关注(0)|答案(1)|浏览(331)

假设只有一台服务器(没有负载均衡器等),如果Javaservlet中的请求写入 static ConcurrentHashMap ,在从Map中删除Map条目之前,Map条目是否立即可用于所有后续servlet请求?换句话说,在对Map的写入返回后,来自另一个servlet请求的后续请求是否有可能找不到Map的任何内容?例如:

import java.util.concurrent.ConcurrentHashMap;

public class IntentTracker {

    private static ConcurrentHashMap<String, AccountUpdateRequest> updateForIntent = new ConcurrentHashMap<>();

    // static access only
    private IntentTracker() {}

    public static void put(String intentId, AccountUpdateRequest accountUpdate) {
        updateForIntent.put(intentId, accountUpdate);
    }

    public static AccountUpdateRequest remove(String intentId) {
        return updateForIntent.remove(intentId);
    }

}

我知道这里的理想情况是使用持久数据存储进行存储和检索,但我想了解 ConcurrentHashMap 会引起一个问题。

s4chpxco

s4chpxco1#

假设只有一台服务器(没有负载均衡器等),如果Javaservlet中的请求写入静态concurrenthashmap,那么在从Map中删除该条目之前,Map条目是否立即可用于所有后续的servlet请求?
多线程编程中的一个问题是定义“后续”和描述事件时间顺序的类似术语。一些相关的承诺 ConcurrentHashMap 那是什么
所有线程都将感知相同的单元素Map修改顺序。
所有线程都将遵循与修改顺序一致的单个元素检索顺序。 Iterator 是的, Spliterator s、 以及 Enumeration Map内容的s将反映Map在特定时间点相对于单个元素修改顺序的状态(没有承诺这个时间点与迭代器的示例化有关,等等…)
说明书上说。。。
检索反映了最近完成的更新操作在开始时的结果。
... 但这必须被视为一个意图声明,而不是一个规范。接下来是这个更正式的表达,它实际上意味着什么:
给定键的更新操作与该键的任何(非null)检索(报告更新值)具有“发生在”关系
实际上,其目的是提供您想要看到的行为,但是从另一个Angular 来看待它在逻辑上更为正确:在没有任何其他修改的情况下,一个线程的读操作r是否感知到另一个线程对Map执行的特定修改w定义了r是发生在w之前还是之后。
换句话说,在对Map的写入返回后,来自另一个servlet请求的后续请求是否有可能找不到Map的任何内容?
如果我们使用“后续”的适当定义,那么答案就是“不”,因为一个请求是否“后续”取决于(除其他外)一个请求是否看到另一个请求对Map的修改。但是如果一个线程确实看到了该修改(或者之后发生的另一个修改以全局一致的顺序对Map进行修改),那么它还将看到另一个线程在修改Map之前在共享内存上执行的所有其他操作。
这并不意味着在一个线程对Map的修改对其他线程可见之前,您必须担心长时间的延迟。你没有。关于单元素操作的计时和内存排序考虑与使用普通的 HashMap 并在互斥锁的保护下执行每次更新和每次读取,但通常不涉及锁 ConcurrentHashMap .

相关问题