ConcurrentHashMap的源码分析-initTable

数组初始化方法,这个方法比较简单,就是初始化一个合适大小的数组

sizeCtl这个要单独说一下,如果没搞懂这个属性的意义,可能会被搞晕

这个标志是在Node数组初始化或者扩容的时候的一个控制位标识,负数代表正在进行初始化或者扩容操作

-1 代表正在初始化

-N 代表有N-1有二个线程正在进行扩容操作,这里不是简单的理解成n个线程,sizeCtl就是-N,这块后续在讲扩容的时候会说明0标识Node数组还没有被初始化,正数代表初始化或者下一次扩容的大小

private final Node<K,V>[] initTable() { 
	Node<K,V>[] tab; int sc; 
	while ((tab = table) == null || tab.length == 0) { 
		if ((sc = sizeCtl) < 0)//被其他线程抢占了初始化的操作,则直接让出自己的CPU时间片 
		Thread.yield(); // lost initialization race; just spin 
		//通过cas操作,将sizeCtl替换为-1,标识当前线程抢占到了初始化资格 
		else if (U.compareAndSwapInt(this, SIZECTL, sc, -1)) { 
			try { 
			if ((tab = table) == null || tab.length == 0) { 
				int n = (sc > 0) ? sc : DEFAULT_CAPACITY;//默认初始容量为16 
				@SuppressWarnings("unchecked") 
				//初始化数组,长度为16,或者初始化在构造ConcurrentHashMap的时候传入的长度 
				Node<K,V>[] nt = (Node<K,V>[])new Node<?,?>[n]; 
				table = tab = nt;//将这个数组赋值给table 
				sc = n - (n >>> 2); //计算下次扩容的大小,实际就是当前容量的0.75倍,这里使用了右移来计算 
				} 
			} finally { 
				sizeCtl = sc; //设置sizeCtl为sc, 如果默认是16的话,那么这个时候
				sc=16*0.75=12 
			} 
			break;
		 } 
	} 
	return tab; 
} 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值