File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
The moose likes Threads and Synchronization and the fly likes Thread safety with ConcurrentHashMap Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Threads and Synchronization
Bookmark "Thread safety with ConcurrentHashMap" Watch "Thread safety with ConcurrentHashMap" New topic

Thread safety with ConcurrentHashMap

R Naijat
Ranch Hand

Joined: Nov 01, 2011
Posts: 40
Hi all,
I have the following class. I use ConcurrentHashMap. I have many threads writing to the maps and a Timer that saves the data in the map every 5 minutes. I manage to achieve thread safety by using putIfAbsent() when I write entries in the map. However, when I read from it and then remove all entries by clear() method, I want no other thread writes to map while I’m in the process of reading the map contents and then removing them. Obviously my code is not threadsafe even with synchronized(lock){}, b/c the thread that owns the lock in saveEntries(), is not necessarily the same thread that writes into my maps in log() method! Unless I lock the whole code in log() with the same lock object!

I was wondering is there any other way to achieve thread safety w/o enforcing synchronizing by an external lock? Any help is greatly appreciated.
Steve Luke

Joined: Jan 28, 2003
Posts: 4181

I haven't really looked at your code, but something you could think of doing is replacing the Map with a new one when it is time to write it out. Make the reference to the map private and don't let it escape. When it is time to save the results, copy the reference to a new local variable, create a new Map and assign it to the original variable. Then use the local variable to save contents. Meanwhile any new entries would be going into the new map and would not interfere with saving.

This only works if the Map you are using is held internal to a class and you can prevent it from being referenced outside that class.

an alternative, of you can't ensure the map doesn't escape, it to create a snapshot copy of the map, save the contents of the copy, then use original.remove(key,value) for each entry in the copied map to safely remove it from the original. This is more work but should be safe without extra locking.

I agree. Here's the link:
subject: Thread safety with ConcurrentHashMap
jQuery in Action, 3rd edition