We have a scenario where we want to decouple an application from a service works over the network.
In this application a number of threads produce prices, and a single thread for the network must transmit the prices as they arrive.
However, as we are consuming the incoming prices, if a new price for a specific item is received before the last one is transmitted we just want to send the new one.
We solve this by putting prices in a map keyed by their ID, and then iterating over the entry set. However, the drawbacks are that we have to copy the map in a synchronized block that excludes the new prices coming in for a time to achieve the copy, and then clear the input map.
Then the process the entry set of the working copy map.
Is there a way to get the best of both worlds i.e. not have the issues surrounding copying maps and using iterators, or the problem of using a queue which just sends things in order, even if an item is effectively to be replaced?
John Coleman, MSTA<br />Sun Certified Programmer for the Java� 2 Platform<br />email@example.com<br />Eurobase banking solutions<br /><a href="http://www.eurobase-international.com/banking" target="_blank" rel="nofollow">http://www.eurobase-international.com/banking</a>
John: Is there a way to get the best of both worlds i.e. not have the issues surrounding copying maps and using iterators, or the problem of using a queue which just sends things in order, even if an item is effectively to be replaced?
Apparently a ConcurrentHashMap seems like an option for you. However, the iterators do not guarantee a reflection of the current state as suggested by the following javadoc comment:
Similarly, Iterators and Enumerations return elements reflecting the state of the hash table at some point at or since the creation of the iterator/enumeration.
So, your stale record problem will most probably exist.
However, what i feel is if you have a queue that only stores the identifiers that needs to be sent and before sending the record you query the HashMap for the "latest" message you can be better off. With the ConcurrentHashMap, get() guarantees to reflect the latest complete operation as suggested by the following javadoc comment:
Retrievals reflect the results of the most recently completed update operations holding upon their onset.
Yes I settled for using ConcurrentHashMap and obtaining an iterator over the keys and then using get to obtain the latest value.
In our application reading is much lower in volume compared to writing to the map, and I think I noted that this map is really designed to work the other way around. I'm not sure whether this matters though.