zoukankan      html  css  js  c++  java
  • Collections.synchronizedMap 详解

    众所周知,HashMap 本身非线程安全的,但是当使用 Collections.synchronizedMap(new HashMap()) 进行包装后就返回一个线程安全的Map。

    怎么实现的呢?今天比较有兴趣就看了 Collections.synchronizedMap 的实现,发现其实还是比较简单的。

    public static <K,V> Map<K,V> synchronizedMap(Map<K,V> m) {
    return new SynchronizedMap<K,V>(m);
    }
    synchronizedMap

    当调用synchronizedMap后返回了一个SynchronizedMap 

        private static class SynchronizedMap<K,V>
        implements Map<K,V>, Serializable {
        // use serialVersionUID from JDK 1.2.2 for interoperability
        private static final long serialVersionUID = 1978198479659022715L;
    
        private final Map<K,V> m;     // Backing Map
            final Object      mutex;    // Object on which to synchronize
    
        SynchronizedMap(Map<K,V> m) {
                if (m==null)
                    throw new NullPointerException();
                this.m = m;
                mutex = this;
            }
    
        SynchronizedMap(Map<K,V> m, Object mutex) {
                this.m = m;
                this.mutex = mutex;
            }
    
        public int size() {
            synchronized(mutex) {return m.size();}
            }
        public boolean isEmpty(){
            synchronized(mutex) {return m.isEmpty();}
            }
        public boolean containsKey(Object key) {
            synchronized(mutex) {return m.containsKey(key);}
            }
        public boolean containsValue(Object value){
            synchronized(mutex) {return m.containsValue(value);}
            }
        public V get(Object key) {
            synchronized(mutex) {return m.get(key);}
            }
    
        public V put(K key, V value) {
            synchronized(mutex) {return m.put(key, value);}
            }
        public V remove(Object key) {
            synchronized(mutex) {return m.remove(key);}
            }
        public void putAll(Map<? extends K, ? extends V> map) {
            synchronized(mutex) {m.putAll(map);}
            }
        public void clear() {
            synchronized(mutex) {m.clear();}
        }
    
        private transient Set<K> keySet = null;
        private transient Set<Map.Entry<K,V>> entrySet = null;
        private transient Collection<V> values = null;
    
        public Set<K> keySet() {
                synchronized(mutex) {
                    if (keySet==null)
                        keySet = new SynchronizedSet<K>(m.keySet(), mutex);
                    return keySet;
                }
        }
    
        public Set<Map.Entry<K,V>> entrySet() {
                synchronized(mutex) {
                    if (entrySet==null)
                        entrySet = new SynchronizedSet<Map.Entry<K,V>>(m.entrySet(), mutex);
                    return entrySet;
                }
        }
    
        public Collection<V> values() {
                synchronized(mutex) {
                    if (values==null)
                        values = new SynchronizedCollection<V>(m.values(), mutex);
                    return values;
                }
            }
    
        public boolean equals(Object o) {
                if (this == o)
                    return true;
                synchronized(mutex) {return m.equals(o);}
            }
        public int hashCode() {
                synchronized(mutex) {return m.hashCode();}
            }
        public String toString() {
            synchronized(mutex) {return m.toString();}
            }
            private void writeObject(ObjectOutputStream s) throws IOException {
            synchronized(mutex) {s.defaultWriteObject();}
            }
        }
    SynchronizedMap

    可以看到SynchronizedMap 是一个实现了Map接口的代理类,该类中对Map接口中的方法使用synchronized 同步关键字来保证对Map的操作是线程安全的。

  • 相关阅读:
    angular11源码探索七[服务二]
    angular11源码探索六[服务基础一]
    有趣的特效,嘤嘤嘤
    angular11学习(十八)
    matplotlib 去掉小方框
    xlrd.biffh.XLRDError 问题报错
    页面点击出现蓝色背景色
    移动端不显示滚动条
    Swiper垂直方向滑动,高度获取不正确的解决方法
    二维树状数组
  • 原文地址:https://www.cnblogs.com/cruze/p/3689249.html
Copyright © 2011-2022 走看看