Java并发编程包中提供的支持并发编程环境下的Map实现ConcurrentHashMap,并发编程通常是在多线程的环境下,需要保证类是线程安全的,ConcurrentHashMap通过Segment来分段,Segment继承了ReentrantLock类,因此支持加锁同步,通过这种方式来保证线程安全。同时通过这种分段的方式,减少每次操作map时都需要执行同步操作而必须阻塞从而无法继续执行的可能,必须等加锁的线程释放锁之后才能继续执行下去,从而提高并发性能。
因为同步操作在Segment上,在执行map操作时,对key计算hash后,由于对不同的key计算出来的hash不可能都一样,从而落在不同的分段上,而能够并发执行。
构造Segment需要指定一个初始容量和一个加载因子,用于指定一个初始容量和设置一个threshold,在执行put操作时,如果map中元素的数目超过了这个threshold,执行rehash和扩容操作。
Threshold设置:
threshold = (int)(newTable.length * loadFactor); |
Segment构造:
Segment(int initialCapacity, float lf) |
Segment最大容量为1 << 30,也就是2的30次方。
static final int MAXIMUM_CAPACITY = 1 << 30; |
The maximum capacity, used if a higher value is implicitly specified by either of the constructors with arguments. MUST be a power of two <= 1<<30 to ensure that entries are indexable using ints. |
这个是Segment中桶的最大容量,但并不是最大可put的元素的最大数量。最大可put的元素的数量为int的最大值,即2的31次方-1。
计算落桶的位置:
int index = hash & (tab.length - 1); |
和普通的HashMap及ConcurrentHashMap一样,默认的初始容量为16;默认的加载因子为0.75。
关键字比较:
e.hash != hash || !key.equals(e.key) |
删除remove操作:
V remove(Object key, int hash, Object value) |
如果value为null,则只匹配key,否则同时匹配key和value。