ConcurrentHashMap源码(二)--initTable
2015-08-26 15:44
423 查看
在ConcurrentHashMap的put方法中,第一次添加元素的时候table是空的(使用空的构造函数),就会执行initTable方法。
下面就来看一下jdk8是怎么初始化这个table的,如何保证并发不出问题。
关于unsafe.compareAndSwap的用法,可以参见我以前的博客 AtomicInteger分析--自实现无锁并发。
下面就来看一下jdk8是怎么初始化这个table的,如何保证并发不出问题。
关于unsafe.compareAndSwap的用法,可以参见我以前的博客 AtomicInteger分析--自实现无锁并发。
private final Node<K,V>[] initTable() { Node<K,V>[] tab; int sc; //这个有个死循环, while ((tab = table) == null || tab.length == 0) { //2.sizeCtl何时为0?看后面 if ((sc = sizeCtl) < 0) Thread.yield(); // lost initialization race; just spin //1.这里有个if,如果没进这个if,则继续循环 //什么时候没进这个if呢? // -就是unsafe.compareAndSwapInt失败的时候, //什么时候失败呢? // -当其他的线程也对sizeCtl进行了修改(内存里实际的值与手上拿的不一样,这个时候就返回false了。svn一样) //2.如果成功了,则进入if,同时,内存中的sizeCtl的值也被修改成了-1,这个时候就可以看到1处做的判断:如果小于0,则放弃此次执行 //3.如果未成功,那继续while: // -这个时候要么其他的线程已经将table初始化好了,table!=null,直接返回table就行了 // -要么其他线程正在初始化这个表,此时的sizeCtl是-1.所以放弃此次执行。(等待其他线程) else if (U.compareAndSwapInt(this, SIZECTL, sc, -1)) { try { if ((tab = table) == null || tab.length == 0) { //这里就是初始化一个table数组 int n = (sc > 0) ? sc : DEFAULT_CAPACITY; @SuppressWarnings("unchecked") Node<K,V>[] nt = (Node<K,V>[])new Node<?,?> ; table = tab = nt; sc = n - (n >>> 2); } } finally { //结束后将sizeCtl设置为新的table的容量(而不是-1) sizeCtl = sc; } //初始化完成了,那就break。 break; } } return tab; }
相关文章推荐
- spring: 加载远程配置
- easyui 绑定数据
- 类的对象内存解析
- c语音中打印参数调用层级即call stack, call trace
- android屏幕适配
- vs2010调试
- PreparedStatement 预编译原理
- USACO-Section 1.3 Prime Cryptarithm(枚举)
- Oracle Study之---Oracle SQL语句中with的使用
- R语言_功效分析
- 使用setBounds()方法需要注意的地方
- 最快排序之"桶排序"
- 二维数组指针
- linux总结应用之六 驱动设备块设备中的中断
- HTML中rel属性分析
- jetty中禁止使用chunked传输数据
- ZooKeeper伪分布式安装
- Java之m2eclipse插件安装
- 自动轮播图
- 排序