在多线程环境中使用HashMap进行定期更新 [英] Usage of HashMap in a multi-threaded environment for regular update

查看:210
本文介绍了在多线程环境中使用HashMap进行定期更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Java应用程序,在该应用程序中,我将其他服务器的一组IP保存在内存中的哈希映射中。哈希映射包含服务器实例ids到服务器IP地址之间的映射。我还将这些服务器信息维护在数据库中以实现持久性。

我试图解决一个简单的问题,我只需要将内存中的服务器信息缓存以便更快地访问。所以我使用hashmap。我需要确保内存中的服务器信息不会过时,并且缓存中的所有服务器都能够响应。



因此,我创建了两个单独的后台后台线程,


  • 一个线程,它从hashmap获取每个条目并对它们进行ping处理。如果任何服务器没有响应,那么它会从hashmap中删除该条目。
  • 另一个线程基本上将数据库条目与此散列映射缓存同步。因此,它查询所有条目数据库,并删除hashmap中不存在于数据库中的条目以及数据库中的新条目,并将它们分别加入到散列映射中。

  • ul>

    在这里,第一个线程运行频率可以让evey持续15秒,第二个线程每5分钟运行一次。

    因为这两个线程都在这里更新缓存,所以我使用了ConcurrentHashMap,因为它会被同步。即使如此,当我阅读多篇文章,文档和一些stackoverflow的帖子,我看到多线程更新hashmap会有风险,就像一个线程迭代hashmap,其他线程可能会触发并开始更新hashmap。

    因此,我如何在这里使用不同的方法来解决这个问题,这样我就不会在应用程序性能,时间和空间复杂性方面干扰JVM,并确保我拥有只有响应服务器条目在我的hashmap中一直是最重要的。

    解决方案

    ConcurrentHashMap保证这一点:


    视图的迭代器是一个弱一致的迭代器,永远不会
    抛出ConcurrentModificationException,并保证遍历
    元素,因为它们在构造迭代器,可能
    (但不能保证)反映
    构造之后的任何修改。


    什么这意味着在最坏的情况下,一个线程所做的更新将不会被第二个线程看到,直到下一次迭代。让我们看看您的应用程序的含义:



    如果在ping线程运行时通过同步线程添加新服务器,在这次迭代中可能不会被打断。只有在15秒后才会在下一次迭代中被ping通。只要你考虑到这个行为(即如果你没有运行第三个线程去除任何在最近15秒内未被ping通的东西或类似的东西),那么这似乎不成问题。



    如果在进行ping操作时同步线程删除了服务器,服务器可能仍然被ping通,但服务器的记录仍将从缓存。再次,不是问题。



    如果pinging线程在进行同步时删除服务器,则同步线程仍可能会在缓存中看到该服务器。再次,我不认为这是一个问题。

    I have a Java application in which I maintain set of IPs of my other servers in a hash map in memory. The hash map contains mapping between servers instance ids to servers ip address. I also maintain these servers information in a database for persistence.

    I am trying to solve a simple problem where I just need to cache the servers information in memory for faster access. So I have used hashmap for that. And I need to make sure that the server information in memory are NOT stale and all the servers in the cache are responsive.

    So I have created two separate background daemon threads where

    • one thread which gets each entry from the hashmap and pings all of them. If any of the server is not responsive, then it removes that entry from the hashmap.
    • Another thread basically synchronizes the database entries with this hashmap cache. Hence it queries all the entries database, and removes the entries in hashmap which are not there in DB and for new of the entries in DB, it pings each of them and adds to the hashmap.

    Here first thread runs frequently lets say for evey 15 seconds and second DB thread runs for every 5 minutes.

    Since both the threads are updating the cache here, I have used ConcurrentHashMap since it will be synchronized. Even then When I read multiple articles, documentations and some of the stackoverflow posts, I see multiple threads updating the hashmap is going to be risky, like when one thread is iterating over the hashmap, other thread may get triggered and start updating the hashmap.

    So How Can I solve this using different approach here so that I don't disturb the JVM in terms of application performance, time and space complexities and make sure that I have only responsive server entries in my hashmap all most all the time.

    解决方案

    ConcurrentHashMap guarantees this:

    The view's iterator is a "weakly consistent" iterator that will never throw ConcurrentModificationException, and guarantees to traverse elements as they existed upon construction of the iterator, and may (but is not guaranteed to) reflect any modifications subsequent to construction.

    What this means is that in the worst case scenario, an update made by one thread won't be seen by the second one until its next iteration. Let's look at what that means for your application:

    If a new server is added by the synchronization thread while the pinging thread is running, it might not be pinged at this iteration. It will be pinged only in the next iteration, after 15 seconds. That doesn't seem to be a problem as long as you take this behavior into account (i.e. if you don't run a third thread that removes anything that hasn't been pinged in the last 15 seconds or something similar)

    If a server is deleted by the synchronization thread while pinging is in progress, the server might still be pinged, but the server's record will still be deleted from the cache. Again, not a problem.

    If the pinging thread removes a server while synchronization is in progress, the synchronization thread might still see that server in the cache. Again, I don't think that's a problem.

    这篇关于在多线程环境中使用HashMap进行定期更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆