import java.util.AbstractMap;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Function;
import com.xkind.collections.util.ReadWriteLockExtend;
public class ThreadSafeMap<K, V> extends AbstractMap<K, V> {
private final Map<K, V> m_map;
private static final ReadWriteLock m_signal = new ReentrantReadWriteLock();
public ThreadSafeMap() {
m_map = new HashMap<K, V>();
}
public ThreadSafeMap(int capacity) {
m_map = new HashMap<K, V>(capacity);
}
public ThreadSafeMap(Map<? extends K, ? extends V> m) {
m_map = new HashMap<K, V>(m);
}
@Override
public int size() {
return ReadWriteLockExtend.performReadLock(m_signal, () -> m_map.size());
}
@Override
public boolean isEmpty() {
return ReadWriteLockExtend.performReadLock(m_signal, () -> m_map.isEmpty());
}
@Override
public boolean containsKey(Object key) {
return ReadWriteLockExtend.performReadLock(m_signal, () -> m_map.containsKey(key));
}
@Override
public boolean containsValue(Object value) {
return ReadWriteLockExtend.performReadLock(m_signal, () -> m_map.containsValue(value));
}
@Override
public V get(Object key) {
return ReadWriteLockExtend.performReadLock(m_signal, () -> m_map.get(key));
}
@Override
public V put(K key, V value) {
return ReadWriteLockExtend.performWriteLock(m_signal, () -> m_map.put(key, value));
}
@Override
public V remove(Object key) {
return ReadWriteLockExtend.performWriteLock(m_signal, () -> m_map.remove(key));
}
@Override
public void putAll(Map<? extends K, ? extends V> m) {
ReadWriteLockExtend.performWriteLock(m_signal, () -> m_map.putAll(m));
}
@Override
public void clear() {
ReadWriteLockExtend.performWriteLock(m_signal, () -> m_map.clear());
}
@Override
public Set<K> keySet() {
return ReadWriteLockExtend.performReadLock(m_signal, () -> m_map.keySet());
}
@Override
public Collection<V> values() {
return ReadWriteLockExtend.performReadLock(m_signal, () -> m_map.values());
}
@Override
public Set<Entry<K, V>> entrySet() {
return ReadWriteLockExtend.performReadLock(m_signal, () -> m_map.entrySet());
}
@Override
public V getOrDefault(Object key, V defaultValue) {
return ReadWriteLockExtend.performReadLock(m_signal, () -> m_map.getOrDefault(key, defaultValue));
}
@Override
public void forEach(BiConsumer<? super K, ? super V> action) {
ReadWriteLockExtend.performReadLock(m_signal, () -> m_map.forEach(action));
}
@Override
public void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) {
ReadWriteLockExtend.performWriteLock(m_signal, () -> m_map.replaceAll(function));
}
@Override
public V putIfAbsent(K key, V value) {
return ReadWriteLockExtend.performWriteLock(m_signal, () -> m_map.putIfAbsent(key, value));
}
@Override
public boolean remove(Object key, Object value) {
return ReadWriteLockExtend.performWriteLock(m_signal, () -> m_map.remove(key, value));
}
@Override
public boolean replace(K key, V oldValue, V newValue) {
return ReadWriteLockExtend.performWriteLock(m_signal, () -> m_map.replace(key, oldValue, newValue));
}
@Override
public V replace(K key, V value) {
return ReadWriteLockExtend.performWriteLock(m_signal, () -> m_map.replace(key, value));
}
@Override
public V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) {
return ReadWriteLockExtend.performReadLock(m_signal, () -> revert().computeIfAbsent(key, mappingFunction));
}
@Override
public V computeIfPresent(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
return ReadWriteLockExtend.performReadLock(m_signal, () -> revert().computeIfPresent(key, remappingFunction));
}
@Override
public V compute(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
return ReadWriteLockExtend.performReadLock(m_signal, () -> revert().compute(key, remappingFunction));
}
@Override
public V merge(K key, V value, BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
return ReadWriteLockExtend.performWriteLock(m_signal, () -> m_map.merge(key, value, remappingFunction));
}
@Override
public String toString() {
return ReadWriteLockExtend.performReadLock(m_signal, () -> revert().toString());
}
// --------------------------------------------------------------------------------------------
private HashMap<K, V> revert() {
if (m_map instanceof HashMap) {
return (HashMap<K, V>) m_map;
} else {
return new HashMap<K, V>(m_map);
}
}
}
ReadWriteLockExtend
package com.xkind.collections.util;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.function.Supplier;
public class ReadWriteLockExtend {
public static void performReadLock(final ReadWriteLock signal, final Runnable runnable) {
signal.readLock().lock();
try {
runnable.run();
} finally {
signal.readLock().unlock();
}
}
public static <T> T performReadLock(final ReadWriteLock signal, final Supplier<T> supplier) {
signal.readLock().lock();
try {
return supplier.get();
} finally {
signal.readLock().unlock();
}
}
public static void performWriteLock(final ReadWriteLock signal, final Runnable runnable) {
signal.writeLock().lock();
try {
runnable.run();
} finally {
signal.writeLock().unlock();
}
}
public static <T> T performWriteLock(final ReadWriteLock signal, final Supplier<T> supplier) {
signal.writeLock().lock();
try {
return supplier.get();
} finally {
signal.writeLock().unlock();
}
}
}