A hash table supporting full concurrency of retrievals and high expected concurrency for updates. This class obeys the same functional specification as java.util.Hashtable, and includes versions of methods corresponding to each method of Hashtable. However, even though all operations
| 237 | * @since 1.5 |
| 238 | */ |
| 239 | @SuppressWarnings("SynchronizationOnLocalVariableOrMethodParameter") |
| 240 | public class ConcurrentHashMap<V> extends AbstractMap<CharSequence, V> |
| 241 | implements ConcurrentMap<CharSequence, V>, Serializable { |
| 242 | static final int HASH_BITS = 0x7fffffff; // usable bits of normal node hash |
| 243 | |
| 244 | /* |
| 245 | * Overview: |
| 246 | * |
| 247 | * The primary design goal of this hash table is to maintain |
| 248 | * concurrent readability (typically method get(), but also |
| 249 | * iterators and related methods) while minimizing update |
| 250 | * contention. Secondary goals are to keep space consumption about |
| 251 | * the same or better than java.util.HashMap, and to support high |
| 252 | * initial insertion rates on an empty table by many threads. |
| 253 | * |
| 254 | * This map usually acts as a binned (bucketed) hash table. Each |
| 255 | * key-value mapping is held in a Node. Most nodes are instances |
| 256 | * of the basic Node class with hash, key, value, and next |
| 257 | * fields. However, various subclasses exist: TreeNodes are |
| 258 | * arranged in balanced trees, not lists. TreeBins hold the roots |
| 259 | * of sets of TreeNodes. ForwardingNodes are placed at the heads |
| 260 | * of bins during resizing. ReservationNodes are used as |
| 261 | * placeholders while establishing values in computeIfAbsent and |
| 262 | * related methods. The types TreeBin, ForwardingNode, and |
| 263 | * ReservationNode do not hold normal user keys, values, or |
| 264 | * hashes, and are readily distinguishable during search etc |
| 265 | * because they have negative hash fields and null key and value |
| 266 | * fields. (These special nodes are either uncommon or transient, |
| 267 | * so the impact of carrying around some unused fields is |
| 268 | * insignificant.) |
| 269 | * |
| 270 | * The table is lazily initialized to a power-of-two size upon the |
| 271 | * first insertion. Each bin in the table normally contains a |
| 272 | * list of Nodes (most often, the list has only zero or one Node). |
| 273 | * Table accesses require volatile/atomic reads, writes, and |
| 274 | * CASes. Because there is no other way to arrange this without |
| 275 | * adding further indirections, we use intrinsics |
| 276 | * (sun.misc.Unsafe) operations. |
| 277 | * |
| 278 | * We use the top (sign) bit of Node hash fields for control |
| 279 | * purposes -- it is available anyway because of addressing |
| 280 | * constraints. Nodes with negative hash fields are specially |
| 281 | * handled or ignored in map methods. |
| 282 | * |
| 283 | * Insertion (via put or its variants) of the first node in an |
| 284 | * empty bin is performed by just CASing it to the bin. This is |
| 285 | * by far the most common case for put operations under most |
| 286 | * key/hash distributions. Other update operations (insert, |
| 287 | * delete, and replace) require locks. We do not want to waste |
| 288 | * the space required to associate a distinct lock object with |
| 289 | * each bin, so instead use the first node of a bin list itself as |
| 290 | * a lock. Locking support for these locks relies on builtin |
| 291 | * "synchronized" monitors. |
| 292 | * |
| 293 | * Using the first node of a list as a lock does not by itself |
| 294 | * suffice though: When a node is locked, any update must first |
| 295 | * validate that it is still the first node after locking it, and |
| 296 | * retry if not. Because new nodes are always appended to lists, |
nothing calls this directly
no test coverage detected
searching dependent graphs…