Search code examples
codenameone

ConcurrentHashMap in Codename One


I need to use the same HashMap from different threads (EDT, a Timer, and maybe the Network Thread). Since Codename One doesn't have a ConcurrentHashMap implementation in its API, I tried to circumvent this issue so:

/**
 * ConcurrentHashMap emulation for Codename One.
 */
public class ConcurrentHashMap<K, V> {

    private static final EasyThread thread = EasyThread.start("concurrentHashMap_Thread");
    private final Map<K, V> map = new HashMap<>();

    public V put(K key, V value) {
        return thread.run(() -> map.put(key, value));
    }

    public V get(K key) {
        return thread.run(() -> map.get(key));
    }

    public V remove(K key) {
        return thread.run(() -> map.remove(key));
    }

}

I have two questions:

  1. Is a code like the above actually necessary in Codename One, when accessing a Map from two or more threads? Is it better to use an HashMap directly?

  2. What do you think about that code? I tried to keep it as simple as possible, but I'm not sure of its correctness.


Solution

  • That code is very correct. It's also very inefficient as you're creating multiple locks to add a new object to a different thread. So you're effectively bringing a tank to a problem that's far simpler.

    The TL;DR is this:

    map = Collections.synchronizedMap(map);
    

    Your code could have been written like this and would have been more efficient:

    public class ConcurrentHashMap<K, V> {
        private static final EasyThread thread = EasyThread.start("concurrentHashMap_Thread");
        private final Map<K, V> map = new HashMap<>();
    
        public synchronized V put(K key, V value) {
            return map.put(key, value);
        }
    
        public synchronized V get(K key) {
            return map.get(key);
        }
    
        public synchronized V remove(K key) {
            return map.remove(key);
        }
    }
    

    But you obviously don't need it since we have the synchronizedMap method...

    So why don't we have ConcurrentHashMap?

    Because we don't run on huge servers. See this article: https://crunchify.com/hashmap-vs-concurrenthashmap-vs-synchronizedmap-how-a-hashmap-can-be-synchronized-in-java/

    The TL;DR of that article is that ConcurrentHashMap makes sense when you have a lot of threads and a lot of server cores. It tries to go the extra mile at limiting synchronization for maximum scale. In mobile that's a huge overkill.