Code: Select all
new FastMap<String, L2PcInstance>().setShared(true);
Code: Select all
new FastMap<String, L2PcInstance>().setShared(true);
Code: Select all
private final Object put(Object key, Object value, int keyHash, boolean concurrent, boolean noReplace, boolean returnEntry) { final FastMap map = getSubMap(keyHash); final Entry[] entries = map._entries; // Atomic. final int mask = entries.length - 1; int slot = -1; for (int i = keyHash >> map._keyShift;; i++) { Entry entry = entries[i & mask]; if (entry == null) { slot = slot < 0 ? i & mask : slot; break; } else if (entry == Entry.NULL) { slot = slot < 0 ? i & mask : slot; } else if ((key == entry._key) || ((keyHash == entry._keyHash) && (_isDirectKeyComparator ? key.equals(entry._key) : _keyComparator.areEqual(key, entry._key)))) { if (noReplace) { return returnEntry ? entry : entry._value; } Object prevValue = entry._value; entry._value = value; return returnEntry ? entry : prevValue; } } // Add new entry (synchronize if concurrent). if (concurrent) { synchronized (this) { return put(key, value, keyHash, false, noReplace, returnEntry); } } // Setup entry. final Entry entry = _tail; entry._key = key; entry._value = value; entry._keyHash = keyHash; if (entry._next == null) { createNewEntries(); } entries[slot] = entry; map._entryCount += ONE_VOLATILE; // Prevents reordering. _tail = _tail._next; if (map._entryCount + map._nullCount > (entries.length >> 1)) { // Table more than half empty. map.resizeTable(_isShared); } return returnEntry ? entry : null; }
DrHouse wrote:BTW pm forsaiken for further info he is a real expert on this
FastMap has a predictable iteration order, which is the order in which keys are inserted into the map (similar to java.util.LinkedHashMap collection class). If the map is marked shared then all operations are thread-safe including iterations over the map's collections. Unlike ConcurrentHashMap, access never blocks; retrieval reflects the map state not older than the last time the accessing threads have been synchronized (for multi-processors systems synchronizing ensures that the CPU internal cache is not stale). In most application it is not a problem because thread synchronization is done at high level (e.g. scheduler) and threads run freely (and quickly) until the next synchronization point. In some cases the "happen before" guarantee is necessary (e.g. to ensure unicity) and threads have to be synchronized explicitly. Whenever possible such synchronization should be performed on the key object itself and the not the whole map. For example:Code: Select all
FastMap<Index, Object> sparseVector = new FastMap<Index, Object>().setShared(true) ... // Put synchronized(index) { // javolution.util.Index instances are unique. sparseVector.put(index, value); } ... // Get synchronized(index) { // Blocking only when accessing the same index. value = sparseVector.get(index); // Latest value guaranteed. }