有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Java并发数据结构

我正在努力解决有趣的并发问题!不确定我是否理解正确,因为我有点困惑

enter image description here

为了线程安全,我想使用ConcurrentMap

ConcurrentHashMap<String, BigDecimal> concurrentHashMap = new ConcurrentHashMap<String, BigDecimal>();

public BigDecimal getPrice(String id){
    return concurrentHashMap.get(id);
} 

public void updatePrice(String id, BigDecimal newPrice){
    concurrentHashMap.put(id, newPrice);
}
  1. 该解决方案能保证线程安全的读/写吗?ConcurrentMap是解决这类问题的好选择吗
  2. 如果我写入"a"键,它会锁定整个映射还是写入"b"键可用
  3. 完成任务的以下部分意味着什么如果在处理价格Pa1所需的时间内,价格Pa2、Pa3和Pa4到达,则应用程序应处理的下一个价格是Pa4,并且应忽略所有以前的价格-可能我把事情搞得太复杂了,但这是否意味着如果新的或更新的价格到达,我就不应该存储和取消价格更新?如果是,那么实现会是什么样子

谢谢你的帮助


共 (3) 个答案

  1. # 1 楼答案

    Will that solution guarantee a thread safe read/write? Is ConcurrentMap is good choice for this type of problem?

    java.util.concurrent.ConcurrentHashMapHashMap的线程安全实现,因此使用它将确保线程安全。但请记住:

    • 即使所有操作都是线程安全的,检索操作不需要锁定,也不支持以阻止所有访问的方式锁定整个表
    • 检索操作(包括get)通常不会阻塞,因此可能与更新操作(包括put和remove)重叠检索反映最近完成的更新操作的结果在开始时保持不变

    阅读Java doc of CHM了解更多信息

    If I write to key "a" will it lock the whole Map or writes to "b" key is available?

    是的,它将为任何写入操作锁定映射,如果正在写入“a”,则写入“b”将不可用,但映射仍将为非阻塞读取

    What does take following part of the task means? If during the time taken to process price Pa1 the prices Pa2, Pa3, and Pa4 arrive, then the next price the application should process is Pa4 and all previous prices should be ignored. - Probably I am overcomplicating things but does that mean I should not store and cancel price update if new more recent price arrive? If yes, then how would implementation look like?

    这仅仅意味着“考虑最新价格”

    考虑到需求,您选择使用映射是一个很好的选择,因为当您使用hashMap.put("pa", 123)时,它将丢弃以前的值,因此每当您读取hashmap时,您将始终读取最新的值

    如果真的不需要实现并发,您可能希望使用simple HashMap。并发应该是需求,而不是选择

  2. # 2 楼答案

    因此,您不会遇到任何死锁情况。请尝试以下操作:或在尝试使用资源之前实现您自己的标志以检查资源是否正在使用

    public synchronized void updatePrice(String id, BigDecimal newPrice){
         concurrentHashMap.put(id, newPrice);
    }
    
  3. # 3 楼答案

    一,ConcurrentHashMap在多线程环境中使用是安全的

    1. 它不会锁定整个地图。很可能您将能够并行写入b

    2. 这是最有趣的部分,也是问题本身。 假设updatePrice函数在存储之前执行一些计算。所以新的价格一个接一个地出现,但你慢慢地一个接一个地储存。。。而排队的价格越来越高

    您必须从输入中读取特定密钥的所有价格-放弃第一个,只取最后一个 如果你说你的{{CD4}}在中间。在真正的处理之前,你是对的。这就像解决问题一样

    But!如果价格经常上涨,每次更新都会在内存堆(eden空间)中生成新对象。您的GC将从堆中清除所有这些价格。因此,有趣的是,要了解您是否可以在不同的处理器上订阅不同的价格,并:全部阅读\take the last