zoukankan      html  css  js  c++  java
  • java1.8中ConcurrentHashMap

    java1.8中的ConcurrentHashMap做了非常大的改动,整个数据结构都发生了变化,已经不存在segment了。所以要好好重新查看下源码。这篇博客是逐步更行的,看一点写一点。

    首先看一个很重要的参数sizeCtl,这是一个volatile变量,从名字就可以看出,这是一个大小控制参数。这个参数当CHM的table正在被某个线程正在初始化或者正在resize的时候是负数。当在初始化的时候,是-1;当在resize的时候,值是1(1+正在执行resize操作的线程数量)。在table初始化之前,它是0,初始化之后的其他时间它是下一次table要变成的大小。好神奇有用的一个参数啊。

    private transient volatile int sizeCtl;

    接下来看initTable函数。这个函数只有在第一次执行普通操作是才会调用。这个函数第一次展示了sizeCtl的威力。当sizeCtl小于0时,说明有其他线程正在初始化table或者resize table,则主动放弃线程。

    否则通过CAS把sizeCtl置为-1,这样其他线程在initTable完成之前,看到的sizeCtl都是-1。然后初始化table,并且sizeCtl置为原来(DEFAULT_CAPACITY,为16)的2倍。

     1 private final Node<K,V>[] initTable() {
     2         Node<K,V>[] tab; int sc;
     3         while ((tab = table) == null || tab.length == 0) {
     4             if ((sc = sizeCtl) < 0)
     5                 Thread.yield(); // lost initialization race; just spin
     6             else if (U.compareAndSwapInt(this, SIZECTL, sc, -1)) {
     7                 try {
     8                     if ((tab = table) == null || tab.length == 0) {
     9                         int n = (sc > 0) ? sc : DEFAULT_CAPACITY;
    10                         @SuppressWarnings("unchecked")
    11                         Node<K,V>[] nt = (Node<K,V>[])new Node<?,?>[n];
    12                         table = tab = nt;
    13                         sc = n - (n >>> 2);
    14                     }
    15                 } finally {
    16                     sizeCtl = sc;
    17                 }
    18                 break;
    19             }
    20         }
    21         return tab;
    22     }
  • 相关阅读:
    宏大的目标
    java tcp ip网络编程(二) 套接字的基本使用
    java socket编程(一)简介
    是么是 API 和 SDK
    Mac 下显示隐藏文件
    iOS-事务相关
    iOS测试一段代码的运行时间
    sqlite3 语句总结
    iOS-scrollview及其子类适配iOS7
    OAuth2.0授权和SSO授权
  • 原文地址:https://www.cnblogs.com/JMLiu/p/8747834.html
Copyright © 2011-2022 走看看