【Java】ThreadSafeMap

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();
        }
    }

}
原文地址:https://www.cnblogs.com/zhuzhongxing/p/14147110.html