Can we use HashMap to store shared data in HttpSession? - java

We are using HashMap to store data in HttpSession (Jetty).
We don't synchronize on put and get.
Is it possible that one request puts data into Map and the other request doesn't see that data in Map because they are from different Threads (Jetty thread pool)?
Maybe we must use ConcurrentHashMap?

You have to make sure that the state of the whole object that you store in a session is consistent between different threads.
Just replacing HashMap with ConcurrentHashMap may not be enough for that.
The only thing that ConcurrentHashMap will ensure is 'happens before' behavior will be enforced on values and keys stored in the map.

Related

Efficient way to read key-value pairs for frequent lookups

I'm storing a few properties(KV pairs) in a hierarchical db(JCR). As part of business logic, i have to lookup these key-value pairs very frequently and each time i have to call a method which goes and retrieves the persisted value.
I'm working on a CMS called AEM and all these key-value pairs are authored using a component and stored as JCR properties. Presently i've written an OSGi service which will go to that node and retrieve the value corresponding to the key and this method gets invoked several several times. Instead of making repeated calls to the service method to retrieve these values, can you suggest an efficient way to do this? OSGi auto-wiring?
First of all, I would suggest you to thing twice if you really need to get rid of (or decrease) node properties reading. Do you have performance issues because of this reading or you have another important reason?
If you still wanna to mess with it, I would suggest you next configuration:
You have a Cache Component, which contains this map with all key-value pairs.
You have Listener, which listens to node's change, which contains this data, and invalidates cache on such event (so cache will be rebuilt next time it accessed).
There is a great variety of cache implementations, or you can use simple map for this.

Best practice for updating HashMap for Object Cache

I'm developing a RESTful web service using Jersey and I'm going to be using a simple object cache that is updating it's data by retrieving records from a database based on a timer. I plan on using a HashMap to store my retrieved data in this cache but my question is what is the best practice for updating this HashMap.
Right now my choices are making the HashMap volatile and anytime an update comes in, create a new HashMap and then assign it when it completes. I could also wrap the HashMap in a synchronized block or use a ReentrantReadWriteLock while updating the HashMap variable directly. I have also thought about using ConcurrentHashMap which seems to have some performance benefits. Are there any significant performance differences and/or drawbacks in using one of these approaches over the other?
Also, when a user updates or inserts a record through my web service API, is it best practice to update the local cache directly once I save the record in the DB or force the cache to do another big data retrieval?
Instead of a HashMap, consider using Guava's cache, which is much more configurable and documents your intention to cache data. Read this example.
Use ConcurrentLinkedHasHMap , it uses LIRS algorithm.
ConcurrentLinkedHashMap implementation is a tweaked version of the ConcurrentHashMap implementation originally coded by Doug Lea and found on OpenJDK 1.6.0_0. We present a concurrent hash map and linked list implementation of the ConcurrentMap interface, with predictable iteration order. This implementation differs from ConcurrentHashMap in that it maintains a doubly-linked list running through all of its entries. This linked list defines the iteration ordering, which is normally the order in which keys were inserted into the map (insertion-order). Note that insertion order is not affected if a key is re-inserted into the map.

hashmap cache in servlet

I am trying to implement a servlet for GPS monitoring and trying create simple cache, because i think that it will be faster then SQL request for every Http Request. simple scheme:
in the init() method, i reads one point for each vehicle into HashMap (vehicle id = key, location in json = value) . after that, some request try to read this points and some request try to update (one vehicle update one item). Of course I want to minimize synchronization so i read javadoc :
http://docs.oracle.com/javase/6/docs/api/java/util/HashMap.html
Note that this implementation is not synchronized. If multiple threads access a hash map concurrently, and at least one of the threads modifies the map structurally, it must be synchronized externally. (A structural modification is any operation that adds or deletes one or more mappings; merely changing the value associated with a key that an instance already contains is not a structural modification.)
If I am right, there is no any synchronization in my task, because i do only "not a structural modification == changing the value associated with a key that an instance already contains)". is it a correct statement?
Use the ConcurrentHashMap it doesn't use synchronization by locks, but by atomic operations.
Wrong. Adding an item to the hash map is a structural modification (and to implement a cache you must add items at some point).
Use java.util.concurrent.ConcurrentHashMap.
if all the entries are read into hashmap in init() and then only read/modified - then yes, all the other threads theoretically do not need to sync, though some problems might arise due to threads caching values, so ConcurrentHashMap would be better.
perhaps rather than implementing cache yourself, use a simple implementation found in Guava library
Caching is not an easy problem - but it is a known one. Before starting, I would carefully measure wheter you really do have a performance problem, and whether caching actually solve it. You may think it should, and you may be right. You may also be horrendously wrong depending on the situation ("Preemptive optimization is the root of all evil"), so measure.
This said, do not implement a cache yourself, use a library doing it for you. I have personnaly good experience with ehcache.
If I understand correctly, you have two types of request:
Read from cache
Write to cache (to update the value)
In this case, you may potentially try to write to the same map twice at the same time, which is what the docs are referring to.
If all requests go through the same piece of code (e.g. an update method which can only be called from one thread) you will not need synchronisation.
If your system is multi-threaded and you have more than one thread or piece of code that writes to the map, you will need to externally synchronise your map or use a ConcurrentHashMap.
For clarity, the reason you need synchronisation is that if you have two threads both trying to update the a JSON value for the same key, who wins? This is either left up to chance or causes exceptions or, worse, buggy behaviour.
Any time you modify the same element from two threads, you need to synchronise on that code or, better still, use a thread-safe version of the data structure if that is applicable.

HashMap or ConcurrentHashMap at Java Controllers?

As explained here: ConcurrentHashMap in Java? concurrent hashmap at Java is thread safe. Java controllers are for web requests and can be called simultaneously from web.
My question is that: Should I use concurrent hash map instead of hash map at Java?
You only need a ConcurrentHashMap if you will be doing concurrent read along with a write or two concurrent writes. If you never change the map after initialization, a regular HashMap is sufficient.
Controllers should generally not contain any request-specific state (any such state should be passed in to the methods as parameters), and if you design your controllers this way, you shouldn't need any synchronization within your controllers.
If you have multiple threads accessing the same hashmap you need to sync this accesss.
You can do that by using an object that has this already implemented like the ConcurrentHashMap or write your own synchronization code and use a plain HashMap.

Java based memcached client, optimization of putting data inside memcache

I have say list of 1000 beans which I need to share among different projects. I use memcache for this purpose. Currently, loop is run over complete list and each bean is stored in memcache with some unique memcache id. I was wondering, instead of putting each and every bean in memcache independently. Put all the beans in hashmap with the same key which is used for storing beans in memcache, and then put this hashmap in memcache.
Will this give me any significant improvement over putting each and every bean individually in memcached. Or will this cause me any trouble because of large size of the object.
Any help is appreciated.
It won't get you any particular benefit -- it'll actually probably be slower on the load -- serialization is serialization, and adding a hashmap wrapper around it just increases the amount of data that needs to be deserialized and populated. for retrievals, assuming that most lookups are desecrate by the key you want to use for your hashmap you'll have a much much slower retrieval time because you'll be pulling down the whole graph just to get to one of it's discreet member info.
Of course if the data is entirely static and you're only using memcached to populate values in various JVM's you can do it that way and just hold onto the hashmap in a static... but then you're multiplying your memory consumption by the number of nodes in the cluster...
I did some optimization work in spymemcached that helps it do the right thing when doing the wire encoding.
This may, or may not help you with your application. In general, just measure when you have performance questions about your app.

Categories