Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lock issue when iterating map. #14

Open
MrSleazy opened this issue Mar 12, 2020 · 0 comments
Open

Lock issue when iterating map. #14

MrSleazy opened this issue Mar 12, 2020 · 0 comments

Comments

@MrSleazy
Copy link

I spend a bit of time debugging this simple case.

@Test
    public void iteratingMapError() {
        db = DBMaker.memoryDB().transactionEnable().make();
        Map<String, String> myStringMap = db.hashMap("fileReadyMap", Serializer.STRING, Serializer.ELSA).createOrOpen();
        myStringMap.put("myKey1", "value1");

        myStringMap.forEach((key, value) -> myStringMap.remove(key)); // stuck forever
        myStringMap.entrySet().removeIf(stringStringEntry -> true); // not stuck
    }

It's a very simple use case:

  • Insert an entry to a map.
  • Execute for each loop within the map
  • Remove entry from map.

I spent some time debugging the locking mechanism in the ReentrantReadWriteLock and HTreeMap classes to see what was going on. Particularly this piece of code here:

private inline fun <E> segmentWrite(segment:Int, body:()->E):E{
        val lock = locks[segment]?.writeLock()
        lock?.lock()
        try {
            return body()
        }finally{
            lock?.unlock()
        }
    }

I filed this as a bug because I encountered this very strange case upon calling remove(key) while doing a for-each in the map. The READ lock is blocking the remove operation and stays stuck forever. You can see here what's going on:
image

After a quick google search, I realized this kind of operation is illegal and that's why you must use an iterator to do this: https://stackoverflow.com/questions/6092642/how-to-remove-a-key-from-hashmap-while-iterating-over-it

However, I think your implementation should check for the READ lock and throw a similar java.util.ConcurrentModificationException in this case, to avoid forever-locking issues like these.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant