前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >并发容器之ConcurrentHashMap(1)

并发容器之ConcurrentHashMap(1)

作者头像
黑洞代码
发布2021-03-19 18:02:47
5640
发布2021-03-19 18:02:47
举报

内容

SynchronizedMapHashtableConcurrentHashMap

SynchronizedMap

HashMap不是线程安全的,即在并发场景下,多个线程共享一个HashMap对象,将会出现程序紊乱。在并发场景下如果要保证一种可行的方式是使用 Collections.synchronizedMap() 方法来包装我们的 HashMap。

代码语言:javascript
复制
/**
 * Collections.synchronizedMap()源码,返回一个SynchronizedMap对象
 */
public static <K,V> Map<K,V> synchronizedMap(Map<K,V> m) {
    return new SynchronizedMap<>(m);
}


/**
 * SynchronizedMap源码
 */
private static class SynchronizedMap<K,V>
        implements Map<K,V>, Serializable {
        private static final long serialVersionUID = 1978198479659022715L;
        /**
         * SynchronizedMap内部依靠Map实现常见的K-V操作。
         */
        private final Map<K,V> m;     // Backing Map
        /**
         * 锁对象,用于控制SynchronizedMap内部的Map对象m的线程安全。
         */
        final Object      mutex;        // Object on which to synchronize

        SynchronizedMap(Map<K,V> m) {
            this.m = Objects.requireNonNull(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();}
        }
        ······

SynchronizedMap示意图

Hashtable

与SynchronizedMap类似,Hashtable也是通过synchronized实现线程安全的,不同的是,Hashtable并没有借助内部的属性作为锁对象,而是在每个方法上加上了synchronized关键字,即Hashtable使用的锁对象是Hashtable对象本身。

代码语言:javascript
复制
public class Hashtable<K,V>
    extends Dictionary<K,V>
    implements Map<K,V>, Cloneable, java.io.Serializable {

    /**
     * The hash table data.
     */
    private transient Entry<?,?>[] table;

    /**
     * The total number of entries in the hash table.
     */
    private transient int count;

    /**
     * The table is rehashed when its size exceeds this threshold.  (The
     * value of this field is (int)(capacity * loadFactor).)
     *
     * @serial
     */
    private int threshold;

    /**
     * Returns the number of keys in this hashtable.
     *
     * @return  the number of keys in this hashtable.
     */
    public synchronized int size() {
        return count;
    }

    /**
     * Tests if this hashtable maps no keys to values.
     *
     * @return  <code>true</code> if this hashtable maps no keys to values;
     *          <code>false</code> otherwise.
     */
    public synchronized boolean isEmpty() {
        return count == 0;
    }
    ······

ConcurrentHashMap

SynchronizedMap和Hashtable都是通过使用一个全局的锁来同步不同线程间的并发访问,因此会带来不可忽视的性能问题——锁的粒度是方法级的,因此同一个方法无法在多线程环境下并发执行。于是就有了 HashMap 的线程安全版本—— ConcurrentHashMap 的诞生。在 ConcurrentHashMap 中,无论是读操作还是写操作都能保证很高的性能:在进行读操作时(几乎)不需要加锁,而在写操作时,JDK1.7JDK1.8分别使用了不同的方式实现了线程安全。

JDK 1.7 ConcurrentHashMap

JDK 1.8 ConcurrentHashMap

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-03-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 落叶飞翔的蜗牛 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 内容
  • SynchronizedMap
  • Hashtable
  • ConcurrentHashMap
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档