1
  1. This is under multi-threading
  2. I have read topics about HashMap and cannot find relevant questions/answers

The code:

 private Map<String, String> eventsForThisCategory;
    ...
    Map<String, String> getEventsForThisCategory() {
        if (eventsForThisCategory == null) {
            Collection<INotificationEventsObj> notificationEvents = notificationEventsIndex.getCategoryNotificationEvents(getCategoryId());
            eventsForThisCategory = new HashMap<String, String>();
            for(INotificationEventsObj notificationEvent : notificationEvents) {
                eventsForThisCategory.put(notificationEvent.getNotificationEventID(), notificationEvent.getNotificationEventName());
            }
            logger.debug("eventsForThisCategory is {}", eventsForThisCategory);
        }
        return eventsForThisCategory;
    }

The output:

app_debug.9.log.gz:07 Apr 2016 13:47:06,661 DEBUG [WirePushNotificationSyncHandler::WirePushNotification.Worker-1] - eventsForThisCategory is {FX_WIRE_DATA=Key Economic Data, ALL_FX_WIRE=All, ALL_FX_WIRE=All, FX_WIRE_HEADLINES=Critical Headlines}

How is it possible?

Volodia
  • 13
  • 5
  • Possible duplicate of [What happens when a duplicate key is put into a HashMap?](http://stackoverflow.com/questions/1669885/what-happens-when-a-duplicate-key-is-put-into-a-hashmap) – Yuri Blanc Apr 08 '16 at 08:38
  • Well, it's not possible. Not for a `HashMap` at least. What kind of concurrency does your code have? Is there whitespace that would differ between the two `ALL_FX_WIRE` keys? – Kayaman Apr 08 '16 at 08:39
  • @Kayaman It is multi-threading. There is no whitespace that would differ the 2 keys. As you can see, it prints out the map, and I don't believe it do an auto-trim for String – Volodia Apr 08 '16 at 08:43
  • @YuriBlanc I will update the question, I already read that topic, have basic understanding of how HashMap work, even know HashMap is not thread safe. – Volodia Apr 08 '16 at 08:44
  • Well, the only thing that comes to mind is a concurrency issue. I assume you can't replicate the behaviour reliably? – Kayaman Apr 08 '16 at 08:49
  • @Kayaman Yeah, I can't replicate it reliably. I also guess it is concurrency issue, but then how to explain it is difficult. Therefore the question. – Volodia Apr 08 '16 at 08:59

2 Answers2

1

I am quite sure that your map won't have two equal keys at the same time. What you see is an effect of modifying the map while iterating iver it (in toString()). When the second "ALL_FX_WIRE" is written, the first one won't be present in the map any more.

You already know that HashMap is not threadsafe. Plus eventsForThisCategory can get modified by another thread while eventsForThisCategory.toString() is running. So this has to be expected.

Make sure eventsForThisCategory is not modified by multiple threads at the same time (or switch to ConcurrentHashMap), and make sure it is not modified while toString() is running (it is called when you create the debug output).

Axel
  • 13,939
  • 5
  • 50
  • 79
  • Ah right, I totally forgot that a `toString` is also an iteration over the Map.Thanks for the answer, – Volodia Apr 08 '16 at 09:32
0

HashMap is not threadSafety in multi-threading. you can try to use Collections.synchronizedMap() to wrap you hashMap instance or use the ConcurrentHashMap maybe better

alardear
  • 3
  • 5