Search code examples
javaconcurrencyconcurrenthashmap

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?


Solution

  • 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.