集合-Collection.SynchronizeMap方法-源码解读

本文深入分析了HashMap如何通过Collections.synchronizedMap方法转变为线程安全的Map。详细解读了源码中对各个方法添加synchronized关键字以确保并发安全的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、从HashMap出发

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

2、源码分析

  public static <K,V> Map<K,V> synchronizedMap(Map<K,V> m) {
  	  //返回一个SynchronizedMap对象
      return new SynchronizedMap<K,V>(m);
  }

  private static class SynchronizedMap<K,V> implements Map<K,V>, Serializable {
      // 使用JDK 1.2.2中的serialVersionUID进行互操作
      private static final long serialVersionUID = 1978198479659022715L;
  
      private final Map<K,V> m;     // 要返回的Map
          final Object      mutex;    // 要同步的对象
  
      SynchronizedMap(Map<K,V> m) {//构造函数1
              if (m==null)
                  throw new NullPointerException();
              this.m = m;
              mutex = this;
          }
  
      SynchronizedMap(Map<K,V> m, Object mutex) {//构造函数2
              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();}
          }
      }

可以看到将每个方法都用synchronized关键字修饰后再返回,实现线程安全。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值