concurrentHashMap 和 hashtable 中使用的锁定机制

locking mechanism used in concurrentHashMap and hashtable

最近在 java 采访中有人问我这个问题。 我稍后尝试搜索它,但找不到确切的答案。 如果任何人有 link o 答案,请告诉我。 所以这是我的问题:

ConcurrentHashMap 和Hashtable 是同步的。 但是它在写操作的同时加锁时使用了哪种加锁机制。

ConcurrentHashMap 的两个主要特点是:

  • 在ConcurrentHashMap上写入时,只锁定了map的一部分
  • 读取通常可以在没有锁定的情况下发生。

可能有两个并行线程同时写入 ConcurrentHashMap。根据 ConcurrentHashMap 的默认实现,最多 16 个线程可以并行写入和读取。但最坏的情况是,如果两个对象位于 ConcurrentHashMap 的同一个段或分区,则无法并行写入。

开源的伟大之处在于您可以直接查找the source code! This bit 特别相关。

ConcurrentHashMap 中的并发非常复杂 - 它将内容分成 Segment 以避免锁定整个 table,并使用 volatile 字段允许无锁并发阅读。

ConcurrentHashMap 使用内部将桶分成段,并且一个特定的段可以由线程锁定以用于写入目的。

Segment 只是一个静态的 class,它是哈希表的特殊版本,并实现了 Reentrantlock 以简化锁定,如

static class Segment<K,V> extends ReentrantLock implements Serializable {
        private static final long serialVersionUID = 2249069246763182397L;
        final float loadFactor;
        Segment(float lf) { this.loadFactor = lf; }
}

Segments 的构造函数调用 ReentrantLock 的无参数构造函数并创建一个非公平锁。