Search code examples
javaconcurrencyhashmapjava.util.concurrent

Read ConcurrentHashMap (or similar) in chunks


I have a program, that has a ConcurrentHashMap where different Threads can add/remove items from the map.

I'm interested to know what's the best approach to read the map in chunks of 25 items. What I want to do is something like this: user clicks on a button and reads 25 items from the map( doesn't matter the order). After that he can click a "Next" button and read another 25 items( that are different from the first 25 ), and so on.

I'm not sure if I can do this with a ConcurrentHashMap . I don't want to use a database , and I want to keep this in memory. I don't think converting the Map into an ArrayList will help, because items are added/ removed from the map, most of the time.

I'm open to any solution, even a 3rd party library.

UPDATE: I'm also not tied to ConcurrentHashMap . I'm just looking for the best solution

UPDATE 2: They keys are String

Thanks


Solution

  • In your case, since String keys are strictly ordered, ConcurrentSkipListMap is a way to go.

    • It is both concurrent and navigable, and can be often used in place of ConcurrentHashMap.
    • get / put / remove are as fast as O(log N).
    • As a bonus you'll get the natural traversal order for free.

    To get the next page from ConcurrentSkipListMap, call tailMap with the last key of the previous page as an anchor and then construct an iterator or a stream from the result submap:

        return map.tailMap(lastKey, false).entrySet()
                .stream()
                .limit(pageSize)
                .collect(Collectors.toList());
    

    Note that tailMap will succeed even if the anchor key is removed from the map. The iteration will proceed from the next key larger than the anchor.


    If keys are not strictly ordered, or if O(1) complexity is required, then you may prefer an alternative suggestion - an open-addressed hash table traversed in the order of cell indices. However there is no such implementation among standard Java classes. The thread-safety of such maps is typically achieved by locking.