Win a copy of Head First Agile this week in the Agile forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

Hashtable vs. HashMap  RSS feed

 
Jeff Kilbride
Greenhorn
Posts: 7
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I have a caching structure in a servlet currently implemented with a Hashtable and I'm wondering if I can convert it to a HashMap for efficiency. The hash contains string arrays and corresponds to data in my database. I preload the hash in the servlet init() method and I have a background thread that updates the cache every six hours -- by creating a completely new hash and replacing the old. If new info is entered into the database between cache updates, I'd like to pick that up and reflect it in my cache. Here's some pseudo-code of what I'm doing:
<pre>
static Hashtable cache
// In doGet() method...
StringArray = retrieve array from Hashtable cache
if StringArray is null {
create sql statement and retrieve info from DB
if data exists in DB {
create new StringArray
add to Hashtable cache
}
}
</pre>
Pretty straightforward. I'm not trying to lock anything based on the keys or values in the hash, it's just storing info to avoid DB lookups. If two nearly simultaneous threads both make it to the DB call I don't really care. The second will just overwrite the first with the same key.
My question is: are individual key assignments and reads, to and from the Hashtable/HashMap, atomic? I'm assuming they are for Hashtables because of the internal synchronization, but what about HashMaps? Can two threads be simultaneously reading from and writing to the same key, so that the reading thread gets corrupted data? I'm afraid that a second thread may read from the cache while the first thread is in the middle of updating that particular key -- so that later in the code I may get some sort of exception due to a corrupted String Array value. When I say exception, I mean Java lang exception (like the Array thinks it has 20 elements, but only has 10 because it read the key halfway through the update process), not an exception generated by my code. Is this possible, or is the individual key unreadable until the update completes?
What exactly is synchronized in a Hashtable that is not synchronized in a HashMap?
Thanks,
--jeff
[This message has been edited by Jeff Kilbride (edited April 25, 2001).]
[This message has been edited by Jeff Kilbride (edited April 25, 2001).]
[This message has been edited by Jeff Kilbride (edited April 25, 2001).]
 
Peter den Haan
author
Ranch Hand
Posts: 3252
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Jeff Kilbride:
I have a caching structure in a servlet currently implemented with a Hashtable and I'm wondering if I can convert it to a HashMap for efficiency.[...] My question is: are individual key assignments and reads, to and from the Hashtable/HashMap, atomic? I'm assuming they are for Hashtables because of the internal synchronization, but what about HashMaps?

No, they are not atomic. You would need to synchronize your HashMap, either explicitly or by using Collections.synchronizedMap(). There is no significant performance difference between this and a Hashtable (but I would personally always prefer using the Collections framework).
What exactly is synchronized in a Hashtable that is not synchronized in a HashMap?

All types of read and write access are synchronized, as in general neither is atomic (but even if they were were atomic, you would need to synchronize or they could break on certain types of multi-processor hardware).
- Peter
 
Jeff Kilbride
Greenhorn
Posts: 7
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ok, then for my example is it sufficient to use a Hashtable with no explicity synchronization in my code? Or do I need to synchronize the entire read/write block like:
<pre>
synchronized (Hashtable) {
StringArray = retrieve from Hash
if StringArray is null {
Build SQL statement
Retrieve from Database
if data exists {
build StringArray
Add to Hashtable
}
}
}
</pre>
This seems a little heavy handed, because I would say 99% of the time the Hash will be read as opposed to written to. If I synchronize the entire block, that will really impact performance.
Any alternatives?
Thanks,
--jeff
 
Peter den Haan
author
Ranch Hand
Posts: 3252
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Jeff Kilbride:
Ok, then for my example is it sufficient to use a Hashtable with no explicity synchronization in my code?

I would think so, since you already indicated that the occasional duplicate SQL query would not be a problem. You certainly would not want to put all your code in a synchronized block, after all, that would render your entire application incommunicado for the duration of the query. Not good.
(You would be able to avoid duplicate queries by keeping track of a query queue and blocking threads if they want the result for a query that is in the queue, but that's probably overkill).
- Peter
 
Jeff Kilbride
Greenhorn
Posts: 7
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks Peter. I appreciate the responses.
I was fairly skeptical about using a HashMap in this instance -- at least an unsynchronized one. Just wanted to get another point of view.
I think queuing and blocking would definitely be overkill in this scenario. I expect the cache to be up to date 99% of the time and the call to the DB to be very rare.
Thanks again!
--jeff
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!