0

I need to have a number of threads which operate on the shared java.util.HashMap.

Each of them will perform single read and write operations (i.e. none will use bulk operations, like putAll()) and I want to make sure there will be no lost updates.

Does synchronized writing guarantees safety? If I do something like this:

writeLock.lock();
double latestValue = map.get(key);
map.put(key, latestValue + diff);
writeLock.unlock();

Will it be enough to avoid lost updates? Will the same approach be enough to achieve repeatable reads?

And, if I used ConcurrentHashMap, can I get rid of my locks safely?

UPD: is there any linear overhead in memory usage if I switch from HashMap to ConcurrentHashMap?

Roman
  • 64,384
  • 92
  • 238
  • 332
  • you have answered your own question , here is a link http://stackoverflow.com/questions/510632/whats-the-difference-between-concurrenthashmap-and-collections-synchronizedmap – Tito Jul 01 '13 at 17:31

2 Answers2

2

Doing updates in synchronized block or after acquiring a lock doesn't guarantee that you will see up-to-date values. For seeing updated/fresh values you are required to take lock for reading as well.

// while writing
lock.lock();
 try {
 map.put(key, value);
}finally {
  lock.unlock();
}

// while reading
lock.lock();
 try {
   map.get(key);
 }finally{
  lock.unlock()
}

And yes ConcurrentHashMap is suited best for your purpose. and you don't need locks either.

Holger
  • 285,553
  • 42
  • 434
  • 765
veritas
  • 2,444
  • 1
  • 21
  • 30
  • +1. There's also the danger of reading the map while it's being modified and getting an exception, but that's unlikely and you'll know it when it happens. Not seeing updates is insidious and can go unnoticed for a long time. – RalphChapin Jul 03 '13 at 15:35
  • @RalphChapin: it’s not that unlikely as it happens in real life. Further, you’re not only risking exceptions but lots of different kind of bugs due to reading stale values. One infamous issue is getting into an infinite loop inside `HashMap.get`… – Holger Apr 01 '16 at 07:58
0

The read/write lock you demonstrate is clearly up to the task, since that's what it's designed to do.

However, since you seem to be mostly updating existing values, you could consider populating your map with AtomicIntegers or similar.

Marko Topolnik
  • 195,646
  • 29
  • 319
  • 436