Use of ConcurrentHashMap eliminates data-visibility troubles?
I've read through Java Concurrency in Practice and am left with this question: when I use a ConcurrentHashMap, what data concurrency issues discussed in Part One of the book do I still need to worry about? Here are a couple of examples from one of my programs:
1. Current position of a trader (a shared integer where 'integer' is the mathematical term)
This number represents what a trader
object currently owns and defines its state. It must read its position to know what to do (look to start a new position, or manage the current one). Trader开发者_如何转开发
methods run on their own thread.
A broker
object is in charge of setting the trader
's position. It will set the position each time one of the trader's orders is filled. Broker
methods run on their own thread.
Both the trader
and broker
are in the same package. Position is implemented as a package-private static ConcurrentHashMap
. The keys are id's of the trader objects. The values are Integer.
External to the package is the application. It gets the traders' positions indirectly with a public getter.
Positions will change at most once every few minutes, so the broker
won't touch the map very often. However, the trader
and application will frequently read. In addition we often have several traders reading the map concurrently.
So using a ConcurrentHashMap this way, I don't have to work about locking and data visibility? The ConcurrentHashMap takes care of everything?
2. The market (bid, ask, last prices)
Pretty much the same situation as position, except now the broker
will very frequently update the prices (up to 10 updates a second during busy times; normally a few times a second). The trader
and application still do frequent reads. The map keys now are codes indicating which stock or future, and the values are objects which hold the market prices.
It seems to work okay, but after reading JCIP, I realize the program can still be broken if things are not implemented correctly. The book talks about the ConcurrentHashMap but doesn't explicitly tell me what issues from Part I we no longer have to address manually. It appears that I don't have to synchronize
anything in this case. Is that correct?
So using a ConcurrentHashMap this way, I don't have to work about locking and data visibility? The ConcurrentHashMap takes care of everything?
This depends on what is in the Map, if I read your example correctly the situation looks like this
static final ConcurrentMap<Integer,Integer> map = ...
class Trader{
public int doRead(){
map.get(someId);
}
}
class Broker{
public void doWrite(){
map.put(someId,someValue);
}
}
If that is the case, then yes all the concurrency is taken care of.
However if the map looks like
static final ConcurrentMap<Integer,Trader> map = ..
class Broker{
public void doWrite(){
map.get(someId).setPosition(somePosition);
}
}
This is NOT thread safe, even though the ConcurrentHashMap locks when you put, all concurrent access of objects at this point must handle their own synchronization.
Yes, ConcurrentHashMap
takes care of visibility and locking as long as:
- values held by map are immutable. Seems to be true in your description, given that your prices objects are immutable;
- you don't have operations on map which must be atomic and can't be expressed as single calls to map's API. For example if you need operation like 'read value from map, perform calculation, and put the result back on the map' to be atomic, you still need to hold explicit lock during this operation, or, better yet, change application so you only use atomic operations of map API such as
get/put/putIfAbsent
.
Unless you are talking about over 100,000 updates/reads per second (very rough guide) I wouldn't consider using multiple threads. The reason is that thread-safe components take many times longer than components which are not. So if a component take 5x longer to be thread safe, you need to be using over 5 threads concurrently to break even, never mind go faster.
Multiple threads are much more useful when you have relatively expensive operations to perform. Updating a position or price is much more efficient as one thread.
精彩评论