Using
java.util.HashMap objects is the most common way of sending update data to Lightstreamer from a Data Adapter.
The correct use of
HashMap objects involves considering a few rules that must be obeyed. We recall two of them, in particular:
- The HashMap class is not thread safe; hence, if multiple threads may call methods on the same instance, all method calls should be explicitly synchronized.
- (this one is imposed by the Lightstreamer Data Adapter interface contract and also applies to any other event object type) After a HashMapinstance has been supplied to Lightstreamer through an update or smartUpdate method call, it can no longer be used by Data Adapter code (plus a few caveats not worth mentioning).
Note that the second rule is also a consequence of the first one. If a
HashMapinstance were used by the Data Adapter after being supplied to
update or
smartUpdate, then concurrent accesses to the object would be possible, even if the Data Adapter should explicitly synchronize its own accesses.
It is important to stress the above rules for one reason: because the consequences of not obeying them can be unpredictable and the final effect can be of a totally different nature and difficult to investigate.
In fact, we observed cases in which lack of synchronization on a
HashMapin a Data Adapter eventually caused calls to
get() and
contains() to get stuck in endless loops.
The race condition could be exploited at any moment and once a loop was entered, it might also cause important locks to be kept, leading to internal buffers growth, thread pools exhaustion and the whole system to become unresponsive.
The insurgence of endless loops in
HashMapoperations due to lack of synchronization is a known fact. See, for instance,
this discussion , where interesting implications arise.
As noted there, although using
ConcurrentHashMapin place of
HashMap prevents all synchronization problems, many prefer to stick to
HashMap because of performance reasons.
The same conditions hold for the Lightstreamer part, as the Data Adapter interface also supports
ConcurrentHashMap, but the management of
HashMap is optimized in some cases.
Consider, however, that rule 2 above still holds for
ConcurrentHashMap. In this case, if a
ConcurrentHashMapinstance were used by the Data Adapter after being supplied to
update or
smartUpdate, no corruption of the internal structure would be possible, but, of course, race conditions between reads by Lightstreamer and further modifications by the Data Adapter could happen.