Java多线程系列--“JUC集合”05之 ConcurrentSkipListMap

 

概要

本章对Java.util.concurrent包中的ConcurrentSkipListMap类进行详细的介绍。内容包括:
ConcurrentSkipListMap介绍
ConcurrentSkipListMap原理和数据结构
ConcurrentSkipListMap函数列表
ConcurrentSkipListMap源码分析(JDK1.7.0_40版本)
ConcurrentSkipListMap示例

转载请注明出处:http://www.cnblogs.com/skywang12345/p/3498556.html

 

ConcurrentSkipListMap介绍

ConcurrentSkipListMap是线程安全的有序的哈希表,适用于高并发的场景。
ConcurrentSkipListMap和TreeMap,它们虽然都是有序的哈希表。但是,第一,它们的线程安全机制不同,TreeMap是非线程安全的,而ConcurrentSkipListMap是线程安全的。第二,ConcurrentSkipListMap是通过跳表实现的,而TreeMap是通过红黑树实现的。
关于跳表(Skip List),它是平衡树的一种替代的数据结构,但是和红黑树不相同的是,跳表对于树的平衡的实现是基于一种随机化的算法的,这样也就是说跳表的插入和删除的工作是比较简单的。

 

ConcurrentSkipListMap原理和数据结构

ConcurrentSkipListMap的数据结构,如下图所示:

Java多线程系列--“JUC集合”05之 ConcurrentSkipListMap

说明

先以数据“7,14,21,32,37,71,85”序列为例,来对跳表进行简单说明。

跳表分为许多层(level),每一层都可以看作是数据的索引,这些索引的意义就是加快跳表查找数据速度。每一层的数据都是有序的,上一层数据是下一层数据的子集,并且第一层(level 1)包含了全部的数据;层次越高,跳跃性越大,包含的数据越少。
跳表包含一个表头,它查找数据时,是从上往下,从左往右进行查找。现在“需要找出值为32的节点”为例,来对比说明跳表和普遍的链表。

情况1:链表中查找“32”节点
路径如下图1-02所示:

Java多线程系列--“JUC集合”05之 ConcurrentSkipListMap

需要4步(红色部分表示路径)。

 

情况2:跳表中查找“32”节点
路径如下图1-03所示:

Java多线程系列--“JUC集合”05之 ConcurrentSkipListMap

忽略索引垂直线路上路径的情况下,只需要2步(红色部分表示路径)。


下面说说Java中ConcurrentSkipListMap的数据结构。
(01) ConcurrentSkipListMap继承于AbstractMap类,也就意味着它是一个哈希表。
(02) Index是ConcurrentSkipListMap的内部类,它与“跳表中的索引相对应”。HeadIndex继承于Index,ConcurrentSkipListMap中含有一个HeadIndex的对象head,head是“跳表的表头”。
(03) Index是跳表中的索引,它包含“右索引的指针(right)”,“下索引的指针(down)”和“哈希表节点node”。node是Node的对象,Node也是ConcurrentSkipListMap中的内部类。

 

ConcurrentSkipListMap函数列表

Java多线程系列--“JUC集合”05之 ConcurrentSkipListMap
// 构造一个新的空映射,该映射按照键的自然顺序进行排序。
ConcurrentSkipListMap()
// 构造一个新的空映射,该映射按照指定的比较器进行排序。
ConcurrentSkipListMap(Comparator<? super K> comparator)
// 构造一个新映射,该映射所包含的映射关系与给定映射包含的映射关系相同,并按照键的自然顺序进行排序。
ConcurrentSkipListMap(Map<? extends K,? extends V> m)
// 构造一个新映射,该映射所包含的映射关系与指定的有序映射包含的映射关系相同,使用的顺序也相同。
ConcurrentSkipListMap(SortedMap<K,? extends V> m)

// 返回与大于等于给定键的最小键关联的键-值映射关系;如果不存在这样的条目,则返回 null。
Map.Entry<K,V> ceilingEntry(K key)
// 返回大于等于给定键的最小键;如果不存在这样的键,则返回 null。
K ceilingKey(K key)
// 从此映射中移除所有映射关系。
void clear()
// 返回此 ConcurrentSkipListMap 实例的浅表副本。
ConcurrentSkipListMap<K,V> clone()
// 返回对此映射中的键进行排序的比较器;如果此映射使用键的自然顺序,则返回 null。
Comparator<? super K> comparator()
// 如果此映射包含指定键的映射关系,则返回 true。
boolean containsKey(Object key)
// 如果此映射为指定值映射一个或多个键,则返回 true。
boolean containsValue(Object value)
// 返回此映射中所包含键的逆序 NavigableSet 视图。
NavigableSet<K> descendingKeySet()
// 返回此映射中所包含映射关系的逆序视图。
ConcurrentNavigableMap<K,V> descendingMap()
// 返回此映射中所包含的映射关系的 Set 视图。
Set<Map.Entry<K,V>> entrySet()
// 比较指定对象与此映射的相等性。
boolean equals(Object o)
// 返回与此映射中的最小键关联的键-值映射关系;如果该映射为空,则返回 null。
Map.Entry<K,V> firstEntry()
// 返回此映射中当前第一个(最低)键。
K firstKey()
// 返回与小于等于给定键的最大键关联的键-值映射关系;如果不存在这样的键,则返回 null。
Map.Entry<K,V> floorEntry(K key)
// 返回小于等于给定键的最大键;如果不存在这样的键,则返回 null。
K floorKey(K key)
// 返回指定键所映射到的值;如果此映射不包含该键的映射关系,则返回 null。
V get(Object key)
// 返回此映射的部分视图,其键值严格小于 toKey。
ConcurrentNavigableMap<K,V> headMap(K toKey)
// 返回此映射的部分视图,其键小于(或等于,如果 inclusive 为 true)toKey。
ConcurrentNavigableMap<K,V> headMap(K toKey, boolean inclusive)
// 返回与严格大于给定键的最小键关联的键-值映射关系;如果不存在这样的键,则返回 null。
Map.Entry<K,V> higherEntry(K key)
// 返回严格大于给定键的最小键;如果不存在这样的键,则返回 null。
K higherKey(K key)
// 如果此映射未包含键-值映射关系,则返回 true。
boolean isEmpty()
// 返回此映射中所包含键的 NavigableSet 视图。
NavigableSet<K> keySet()
// 返回与此映射中的最大键关联的键-值映射关系;如果该映射为空,则返回 null。
Map.Entry<K,V> lastEntry()
// 返回映射中当前最后一个(最高)键。
K lastKey()
// 返回与严格小于给定键的最大键关联的键-值映射关系;如果不存在这样的键,则返回 null。
Map.Entry<K,V> lowerEntry(K key)
// 返回严格小于给定键的最大键;如果不存在这样的键,则返回 null。
K lowerKey(K key)
// 返回此映射中所包含键的 NavigableSet 视图。
NavigableSet<K> navigableKeySet()
// 移除并返回与此映射中的最小键关联的键-值映射关系;如果该映射为空,则返回 null。
Map.Entry<K,V> pollFirstEntry()
// 移除并返回与此映射中的最大键关联的键-值映射关系;如果该映射为空,则返回 null。
Map.Entry<K,V> pollLastEntry()
// 将指定值与此映射中的指定键关联。
V put(K key, V value)
// 如果指定键已经不再与某个值相关联,则将它与给定值关联。
V putIfAbsent(K key, V value)
// 从此映射中移除指定键的映射关系(如果存在)。
V remove(Object key)
// 只有目前将键的条目映射到给定值时,才移除该键的条目。
boolean remove(Object key, Object value)
// 只有目前将键的条目映射到某一值时,才替换该键的条目。
V replace(K key, V value)
// 只有目前将键的条目映射到给定值时,才替换该键的条目。
boolean replace(K key, V oldValue, V newValue)
// 返回此映射中的键-值映射关系数。
int size()
// 返回此映射的部分视图,其键的范围从 fromKey 到 toKey。
ConcurrentNavigableMap<K,V> subMap(K fromKey, boolean fromInclusive, K toKey, boolean toInclusive)
// 返回此映射的部分视图,其键值的范围从 fromKey(包括)到 toKey(不包括)。
ConcurrentNavigableMap<K,V> subMap(K fromKey, K toKey)
// 返回此映射的部分视图,其键大于等于 fromKey。
ConcurrentNavigableMap<K,V> tailMap(K fromKey)
// 返回此映射的部分视图,其键大于(或等于,如果 inclusive 为 true)fromKey。
ConcurrentNavigableMap<K,V> tailMap(K fromKey, boolean inclusive)
// 返回此映射中所包含值的 Collection 视图。
Collection<V> values()
Java多线程系列--“JUC集合”05之 ConcurrentSkipListMap

 

ConcurrentSkipListMap源码分析(JDK1.7.0_40版本)

ConcurrentSkipListMap.java的完整源码如下:

Java多线程系列--“JUC集合”05之 ConcurrentSkipListMap
   1 /*
   2  * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
   3  *
   4  *
   5  *
   6  *
   7  *
   8  *
   9  *
  10  *
  11  *
  12  *
  13  *
  14  *
  15  *
  16  *
  17  *
  18  *
  19  *
  20  *
  21  *
  22  *
  23  */
  24 
  25 /*
  26  *
  27  *
  28  *
  29  *
  30  *
  31  * Written by Doug Lea with assistance from members of JCP JSR-166
  32  * Expert Group and released to the public domain, as explained at
  33  * http://creativecommons.org/publicdomain/zero/1.0/
  34  */
  35 
  36 package java.util.concurrent;
  37 import java.util.*;
  38 import java.util.concurrent.atomic.*;
  39 
  40 /**
  41  * A scalable concurrent {@link ConcurrentNavigableMap} implementation.
  42  * The map is sorted according to the {@linkplain Comparable natural
  43  * ordering} of its keys, or by a {@link Comparator} provided at map
  44  * creation time, depending on which constructor is used.
  45  *
  46  * <p>This class implements a concurrent variant of <a
  47  * href="http://en.wikipedia.org/wiki/Skip_list" target="_top">SkipLists</a>
  48  * providing expected average <i>log(n)</i> time cost for the
  49  * <tt>containsKey</tt>, <tt>get</tt>, <tt>put</tt> and
  50  * <tt>remove</tt> operations and their variants.  Insertion, removal,
  51  * update, and access operations safely execute concurrently by
  52  * multiple threads.  Iterators are <i>weakly consistent</i>, returning
  53  * elements reflecting the state of the map at some point at or since
  54  * the creation of the iterator.  They do <em>not</em> throw {@link
  55  * ConcurrentModificationException}, and may proceed concurrently with
  56  * other operations. Ascending key ordered views and their iterators
  57  * are faster than descending ones.
  58  *
  59  * <p>All <tt>Map.Entry</tt> pairs returned by methods in this class
  60  * and its views represent snapshots of mappings at the time they were
  61  * produced. They do <em>not</em> support the <tt>Entry.setValue</tt>
  62  * method. (Note however that it is possible to change mappings in the
  63  * associated map using <tt>put</tt>, <tt>putIfAbsent</tt>, or
  64  * <tt>replace</tt>, depending on exactly which effect you need.)
  65  *
  66  * <p>Beware that, unlike in most collections, the <tt>size</tt>
  67  * method is <em>not</em> a constant-time operation. Because of the
  68  * asynchronous nature of these maps, determining the current number
  69  * of elements requires a traversal of the elements, and so may report
  70  * inaccurate results if this collection is modified during traversal.
  71  * Additionally, the bulk operations <tt>putAll</tt>, <tt>equals</tt>,
  72  * <tt>toArray</tt>, <tt>containsValue</tt>, and <tt>clear</tt> are
  73  * <em>not</em> guaranteed to be performed atomically. For example, an
  74  * iterator operating concurrently with a <tt>putAll</tt> operation
  75  * might view only some of the added elements.
  76  *
  77  * <p>This class and its views and iterators implement all of the
  78  * <em>optional</em> methods of the {@link Map} and {@link Iterator}
  79  * interfaces. Like most other concurrent collections, this class does
  80  * <em>not</em> permit the use of <tt>null</tt> keys or values because some
  81  * null return values cannot be reliably distinguished from the absence of
  82  * elements.
  83  *
  84  * <p>This class is a member of the
  85  * <a href="{@docRoot}/../technotes/guides/collections/index.html">
  86  * Java Collections Framework</a>.
  87  *
  88  * @author Doug Lea
  89  * @param <K> the type of keys maintained by this map
  90  * @param <V> the type of mapped values
  91  * @since 1.6
  92  */
  93 public class ConcurrentSkipListMap<K,V> extends AbstractMap<K,V>
  94     implements ConcurrentNavigableMap<K,V>,
  95                Cloneable,
  96                java.io.Serializable {
  97     /*
  98      * This class implements a tree-like two-dimensionally linked skip
  99      * list in which the index levels are represented in separate
 100      * nodes from the base nodes holding data.  There are two reasons
 101      * for taking this approach instead of the usual array-based
 102      * structure: 1) Array based implementations seem to encounter
 103      * more complexity and overhead 2) We can use cheaper algorithms
 104      * for the heavily-traversed index lists than can be used for the
 105      * base lists.  Here‘s a picture of some of the basics for a
 106      * possible list with 2 levels of index:
 107      *
 108      * Head nodes          Index nodes
 109      * +-+    right        +-+                      +-+
 110      * |2|---------------->| |--------------------->| |->null
 111      * +-+                 +-+                      +-+
 112      *  | down              |                        |
 113      *  v                   v                        v
 114      * +-+            +-+  +-+       +-+            +-+       +-+
 115      * |1|----------->| |->| |------>| |----------->| |------>| |->null
 116      * +-+            +-+  +-+       +-+            +-+       +-+
 117      *  v              |    |         |              |         |
 118      * Nodes  next     v    v         v              v         v
 119      * +-+  +-+  +-+  +-+  +-+  +-+  +-+  +-+  +-+  +-+  +-+  +-+
 120      * | |->|A|->|B|->|C|->|D|->|E|->|F|->|G|->|H|->|I|->|J|->|K|->null
 121      * +-+  +-+  +-+  +-+  +-+  +-+  +-+  +-+  +-+  +-+  +-+  +-+
 122      *
 123      * The base lists use a variant of the HM linked ordered set
 124      * algorithm. See Tim Harris, "A pragmatic implementation of
 125      * non-blocking linked lists"
 126      * http://www.cl.cam.ac.uk/~tlh20/publications.html and Maged
 127      * Michael "High Performance Dynamic Lock-Free Hash Tables and
 128      * List-Based Sets"
 129      * http://www.research.ibm.com/people/m/michael/pubs.htm.  The
 130      * basic idea in these lists is to mark the "next" pointers of
 131      * deleted nodes when deleting to avoid conflicts with concurrent
 132      * insertions, and when traversing to keep track of triples
 133      * (predecessor, node, successor) in order to detect when and how
 134      * to unlink these deleted nodes.
 135      *
 136      * Rather than using mark-bits to mark list deletions (which can
 137      * be slow and space-intensive using AtomicMarkedReference), nodes
 138      * use direct CAS‘able next pointers.  On deletion, instead of
 139      * marking a pointer, they splice in another node that can be
 140      * thought of as standing for a marked pointer (indicating this by
 141      * using otherwise impossible field values).  Using plain nodes
 142      * acts roughly like "boxed" implementations of marked pointers,
 143      * but uses new nodes only when nodes are deleted, not for every
 144      * link.  This requires less space and supports faster
 145      * traversal. Even if marked references were better supported by
 146      * JVMs, traversal using this technique might still be faster
 147      * because any search need only read ahead one more node than
 148      * otherwise required (to check for trailing marker) rather than
 149      * unmasking mark bits or whatever on each read.
 150      *
 151      * This approach maintains the essential property needed in the HM
 152      * algorithm of changing the next-pointer of a deleted node so
 153      * that any other CAS of it will fail, but implements the idea by
 154      * changing the pointer to point to a different node, not by
 155      * marking it.  While it would be possible to further squeeze
 156      * space by defining marker nodes not to have key/value fields, it
 157      * isn‘t worth the extra type-testing overhead.  The deletion
 158      * markers are rarely encountered during traversal and are
 159      * normally quickly garbage collected. (Note that this technique
 160      * would not work well in systems without garbage collection.)
 161      *
 162      * In addition to using deletion markers, the lists also use
 163      * nullness of value fields to indicate deletion, in a style
 164      * similar to typical lazy-deletion schemes.  If a node‘s value is
 165      * null, then it is considered logically deleted and ignored even
 166      * though it is still reachable. This maintains proper control of
 167      * concurrent replace vs delete operations -- an attempted replace
 168      * must fail if a delete beat it by nulling field, and a delete
 169      * must return the last non-null value held in the field. (Note:
 170      * Null, rather than some special marker, is used for value fields
 171      * here because it just so happens to mesh with the Map API
 172      * requirement that method get returns null if there is no
 173      * mapping, which allows nodes to remain concurrently readable
 174      * even when deleted. Using any other marker value here would be
 175      * messy at best.)
 176      *
 177      * Here‘s the sequence of events for a deletion of node n with
 178      * predecessor b and successor f, initially:
 179      *
 180      *        +------+       +------+      +------+
 181      *   ...  |   b  |------>|   n  |----->|   f  | ...
 182      *        +------+       +------+      +------+
 183      *
 184      * 1. CAS n‘s value field from non-null to null.
 185      *    From this point on, no public operations encountering
 186      *    the node consider this mapping to exist. However, other
 187      *    ongoing insertions and deletions might still modify
 188      *    n‘s next pointer.
 189      *
 190      * 2. CAS n‘s next pointer to point to a new marker node.
 191      *    From this point on, no other nodes can be appended to n.
 192      *    which avoids deletion errors in CAS-based linked lists.
 193      *
 194      *        +------+       +------+      +------+       +------+
 195      *   ...  |   b  |------>|   n  |----->|marker|------>|   f  | ...
 196      *        +------+       +------+      +------+       +------+
 197      *
 198      * 3. CAS b‘s next pointer over both n and its marker.
 199      *    From this point on, no new traversals will encounter n,
 200      *    and it can eventually be GCed.
 201      *        +------+                                    +------+
 202      *   ...  |   b  |----------------------------------->|   f  | ...
 203      *        +------+                                    +------+
 204      *
 205      * A failure at step 1 leads to simple retry due to a lost race
 206      * with another operation. Steps 2-3 can fail because some other
 207      * thread noticed during a traversal a node with null value and
 208      * helped out by marking and/or unlinking.  This helping-out
 209      * ensures that no thread can become stuck waiting for progress of
 210      * the deleting thread.  The use of marker nodes slightly
 211      * complicates helping-out code because traversals must track
 212      * consistent reads of up to four nodes (b, n, marker, f), not
 213      * just (b, n, f), although the next field of a marker is
 214      * immutable, and once a next field is CAS‘ed to point to a
 215      * marker, it never again changes, so this requires less care.
 216      *
 217      * Skip lists add indexing to this scheme, so that the base-level
 218      * traversals start close to the locations being found, inserted
 219      * or deleted -- usually base level traversals only traverse a few
 220      * nodes. This doesn‘t change the basic algorithm except for the
 221      * need to make sure base traversals start at predecessors (here,
 222      * b) that are not (structurally) deleted, otherwise retrying
 223      * after processing the deletion.
 224      *
 225      * Index levels are maintained as lists with volatile next fields,
 226      * using CAS to link and unlink.  Races are allowed in index-list
 227      * operations that can (rarely) fail to link in a new index node
 228      * or delete one. (We can‘t do this of course for data nodes.)
 229      * However, even when this happens, the index lists remain sorted,
 230      * so correctly serve as indices.  This can impact performance,
 231      * but since skip lists are probabilistic anyway, the net result
 232      * is that under contention, the effective "p" value may be lower
 233      * than its nominal value. And race windows are kept small enough
 234      * that in practice these failures are rare, even under a lot of
 235      * contention.
 236      *
 237      * The fact that retries (for both base and index lists) are
 238      * relatively cheap due to indexing allows some minor
 239      * simplifications of retry logic. Traversal restarts are
 240      * performed after most "helping-out" CASes. This isn‘t always
 241      * strictly necessary, but the implicit backoffs tend to help
 242      * reduce other downstream failed CAS‘s enough to outweigh restart
 243      * cost.  This worsens the worst case, but seems to improve even
 244      * highly contended cases.
 245      *
 246      * Unlike most skip-list implementations, index insertion and
 247      * deletion here require a separate traversal pass occuring after
 248      * the base-level action, to add or remove index nodes.  This adds
 249      * to single-threaded overhead, but improves contended
 250      * multithreaded performance by narrowing interference windows,
 251      * and allows deletion to ensure that all index nodes will be made
 252      * unreachable upon return from a public remove operation, thus
 253      * avoiding unwanted garbage retention. This is more important
 254      * here than in some other data structures because we cannot null
 255      * out node fields referencing user keys since they might still be
 256      * read by other ongoing traversals.
 257      *
 258      * Indexing uses skip list parameters that maintain good search
 259      * performance while using sparser-than-usual indices: The
 260      * hardwired parameters k=1, p=0.5 (see method randomLevel) mean
 261      * that about one-quarter of the nodes have indices. Of those that
 262      * do, half have one level, a quarter have two, and so on (see
 263      * Pugh‘s Skip List Cookbook, sec 3.4).  The expected total space
 264      * requirement for a map is slightly less than for the current
 265      * implementation of java.util.TreeMap.
 266      *
 267      * Changing the level of the index (i.e, the height of the
 268      * tree-like structure) also uses CAS. The head index has initial
 269      * level/height of one. Creation of an index with height greater
 270      * than the current level adds a level to the head index by
 271      * CAS‘ing on a new top-most head. To maintain good performance
 272      * after a lot of removals, deletion methods heuristically try to
 273      * reduce the height if the topmost levels appear to be empty.
 274      * This may encounter races in which it possible (but rare) to
 275      * reduce and "lose" a level just as it is about to contain an
 276      * index (that will then never be encountered). This does no
 277      * structural harm, and in practice appears to be a better option
 278      * than allowing unrestrained growth of levels.
 279      *
 280      * The code for all this is more verbose than you‘d like. Most
 281      * operations entail locating an element (or position to insert an
 282      * element). The code to do this can‘t be nicely factored out
 283      * because subsequent uses require a snapshot of predecessor
 284      * and/or successor and/or value fields which can‘t be returned
 285      * all at once, at least not without creating yet another object
 286      * to hold them -- creating such little objects is an especially
 287      * bad idea for basic internal search operations because it adds
 288      * to GC overhead.  (This is one of the few times I‘ve wished Java
 289      * had macros.) Instead, some traversal code is interleaved within
 290      * insertion and removal operations.  The control logic to handle
 291      * all the retry conditions is sometimes twisty. Most search is
 292      * broken into 2 parts. findPredecessor() searches index nodes
 293      * only, returning a base-level predecessor of the key. findNode()
 294      * finishes out the base-level search. Even with this factoring,
 295      * there is a fair amount of near-duplication of code to handle
 296      * variants.
 297      *
 298      * For explanation of algorithms sharing at least a couple of
 299      * features with this one, see Mikhail Fomitchev‘s thesis
 300      * (http://www.cs.yorku.ca/~mikhail/), Keir Fraser‘s thesis
 301      * (http://www.cl.cam.ac.uk/users/kaf24/), and Hakan Sundell‘s
 302      * thesis (http://www.cs.chalmers.se/~phs/).
 303      *
 304      * Given the use of tree-like index nodes, you might wonder why
 305      * this doesn‘t use some kind of search tree instead, which would
 306      * support somewhat faster search operations. The reason is that
 307      * there are no known efficient lock-free insertion and deletion
 308      * algorithms for search trees. The immutability of the "down"
 309      * links of index nodes (as opposed to mutable "left" fields in
 310      * true trees) makes this tractable using only CAS operations.
 311      *
 312      * Notation guide for local variables
 313      * Node:         b, n, f    for  predecessor, node, successor
 314      * Index:        q, r, d    for index node, right, down.
 315      *               t          for another index node
 316      * Head:         h
 317      * Levels:       j
 318      * Keys:         k, key
 319      * Values:       v, value
 320      * Comparisons:  c
 321      */
 322 
 323     private static final long serialVersionUID = -8627078645895051609L;
 324 
 325     /**
 326      * Generates the initial random seed for the cheaper per-instance
 327      * random number generators used in randomLevel.
 328      */
 329     private static final Random seedGenerator = new Random();
 330 
 331     /**
 332      * Special value used to identify base-level header
 333      */
 334     private static final Object BASE_HEADER = new Object();
 335 
 336     /**
 337      * The topmost head index of the skiplist.
 338      */
 339     private transient volatile HeadIndex<K,V> head;
 340 
 341     /**
 342      * The comparator used to maintain order in this map, or null
 343      * if using natural ordering.
 344      * @serial
 345      */
 346     private final Comparator<? super K> comparator;
 347 
 348     /**
 349      * Seed for simple random number generator.  Not volatile since it
 350      * doesn‘t matter too much if different threads don‘t see updates.
 351      */
 352     private transient int randomSeed;
 353 
 354     /** Lazily initialized key set */
 355     private transient KeySet keySet;
 356     /** Lazily initialized entry set */
 357     private transient EntrySet entrySet;
 358     /** Lazily initialized values collection */
 359     private transient Values values;
 360     /** Lazily initialized descending key set */
 361     private transient ConcurrentNavigableMap<K,V> descendingMap;
 362 
 363     /**
 364      * Initializes or resets state. Needed by constructors, clone,
 365      * clear, readObject. and ConcurrentSkipListSet.clone.
 366      * (Note that comparator must be separately initialized.)
 367      */
 368     final void initialize() {
 369         keySet = null;
 370         entrySet = null;
 371         values = null;
 372         descendingMap = null;
 373         randomSeed = seedGenerator.nextInt() | 0x0100; // ensure nonzero
 374         head = new HeadIndex<K,V>(new Node<K,V>(null, BASE_HEADER, null),
 375                                   null, null, 1);
 376     }
 377 
 378     /**
 379      * compareAndSet head node
 380      */
 381     private boolean casHead(HeadIndex<K,V> cmp, HeadIndex<K,V> val) {
 382         return UNSAFE.compareAndSwapObject(this, headOffset, cmp, val);
 383     }
 384 
 385     /* ---------------- Nodes -------------- */
 386 
 387     /**
 388      * Nodes hold keys and values, and are singly linked in sorted
 389      * order, possibly with some intervening marker nodes. The list is
 390      * headed by a dummy node accessible as head.node. The value field
 391      * is declared only as Object because it takes special non-V
 392      * values for marker and header nodes.
 393      */
 394     static final class Node<K,V> {
 395         final K key;
 396         volatile Object value;
 397         volatile Node<K,V> next;
 398 
 399         /**
 400          * Creates a new regular node.
 401          */
 402         Node(K key, Object value, Node<K,V> next) {
 403             this.key = key;
 404             this.value = value;
 405             this.next = next;
 406         }
 407 
 408         /**
 409          * Creates a new marker node. A marker is distinguished by
 410          * having its value field point to itself.  Marker nodes also
 411          * have null keys, a fact that is exploited in a few places,
 412          * but this doesn‘t distinguish markers from the base-level
 413          * header node (head.node), which also has a null key.
 414          */
 415         Node(Node<K,V> next) {
 416             this.key = null;
 417             this.value = this;
 418             this.next = next;
 419         }
 420 
 421         /**
 422          * compareAndSet value field
 423          */
 424         boolean casValue(Object cmp, Object val) {
 425             return UNSAFE.compareAndSwapObject(this, valueOffset, cmp, val);
 426         }
 427 
 428         /**
 429          * compareAndSet next field
 430          */
 431         boolean casNext(Node<K,V> cmp, Node<K,V> val) {
 432             return UNSAFE.compareAndSwapObject(this, nextOffset, cmp, val);
 433         }
 434 
 435         /**
 436          * Returns true if this node is a marker. This method isn‘t
 437          * actually called in any current code checking for markers
 438          * because callers will have already read value field and need
 439          * to use that read (not another done here) and so directly
 440          * test if value points to node.
 441          * @param n a possibly null reference to a node
 442          * @return true if this node is a marker node
 443          */
 444         boolean isMarker() {
 445             return value == this;
 446         }
 447 
 448         /**
 449          * Returns true if this node is the header of base-level list.
 450          * @return true if this node is header node
 451          */
 452         boolean isBaseHeader() {
 453             return value == BASE_HEADER;
 454         }
 455 
 456         /**
 457          * Tries to append a deletion marker to this node.
 458          * @param f the assumed current successor of this node
 459          * @return true if successful
 460          */
 461         boolean appendMarker(Node<K,V> f) {
 462             return casNext(f, new Node<K,V>(f));
 463         }
 464 
 465         /**
 466          * Helps out a deletion by appending marker or unlinking from
 467          * predecessor. This is called during traversals when value
 468          * field seen to be null.
 469          * @param b predecessor
 470          * @param f successor
 471          */
 472         void helpDelete(Node<K,V> b, Node<K,V> f) {
 473             /*
 474              * Rechecking links and then doing only one of the
 475              * help-out stages per call tends to minimize CAS
 476              * interference among helping threads.
 477              */
 478             if (f == next && this == b.next) {
 479                 if (f == null || f.value != f) // not already marked
 480                     appendMarker(f);
 481                 else
 482                     b.casNext(this, f.next);
 483             }
 484         }
 485 
 486         /**
 487          * Returns value if this node contains a valid key-value pair,
 488          * else null.
 489          * @return this node‘s value if it isn‘t a marker or header or
 490          * is deleted, else null.
 491          */
 492         V getValidValue() {
 493             Object v = value;
 494             if (v == this || v == BASE_HEADER)
 495                 return null;
 496             return (V)v;
 497         }
 498 
 499         /**
 500          * Creates and returns a new SimpleImmutableEntry holding current
 501          * mapping if this node holds a valid value, else null.
 502          * @return new entry or null
 503          */
 504         AbstractMap.SimpleImmutableEntry<K,V> createSnapshot() {
 505             V v = getValidValue();
 506             if (v == null)
 507                 return null;
 508             return new AbstractMap.SimpleImmutableEntry<K,V>(key, v);
 509         }
 510 
 511         // UNSAFE mechanics
 512 
 513         private static final sun.misc.Unsafe UNSAFE;
 514         private static final long valueOffset;
 515         private static final long nextOffset;
 516 
 517         static {
 518             try {
 519                 UNSAFE = sun.misc.Unsafe.getUnsafe();
 520                 Class k = Node.class;
 521                 valueOffset = UNSAFE.objectFieldOffset
 522                     (k.getDeclaredField("value"));
 523                 nextOffset = UNSAFE.objectFieldOffset
 524                     (k.getDeclaredField("next"));
 525             } catch (Exception e) {
 526                 throw new Error(e);
 527             }
 528         }
 529     }
 530 
 531     /* ---------------- Indexing -------------- */
 532 
 533     /**
 534      * Index nodes represent the levels of the skip list.  Note that
 535      * even though both Nodes and Indexes have forward-pointing
 536      * fields, they have different types and are handled in different
 537      * ways, that can‘t nicely be captured by placing field in a
 538      * shared abstract class.
 539      */
 540     static class Index<K,V> {
 541         final Node<K,V> node;
 542         final Index<K,V> down;
 543         volatile Index<K,V> right;
 544 
 545         /**
 546          * Creates index node with given values.
 547          */
 548         Index(Node<K,V> node, Index<K,V> down, Index<K,V> right) {
 549             this.node = node;
 550             this.down = down;
 551             this.right = right;
 552         }
 553 
 554         /**
 555          * compareAndSet right field
 556          */
 557         final boolean casRight(Index<K,V> cmp, Index<K,V> val) {
 558             return UNSAFE.compareAndSwapObject(this, rightOffset, cmp, val);
 559         }
 560 
 561         /**
 562          * Returns true if the node this indexes has been deleted.
 563          * @return true if indexed node is known to be deleted
 564          */
 565         final boolean indexesDeletedNode() {
 566             return node.value == null;
 567         }
 568 
 569         /**
 570          * Tries to CAS newSucc as successor.  To minimize races with
 571          * unlink that may lose this index node, if the node being
 572          * indexed is known to be deleted, it doesn‘t try to link in.
 573          * @param succ the expected current successor
 574          * @param newSucc the new successor
 575          * @return true if successful
 576          */
 577         final boolean link(Index<K,V> succ, Index<K,V> newSucc) {
 578             Node<K,V> n = node;
 579             newSucc.right = succ;
 580             return n.value != null && casRight(succ, newSucc);
 581         }
 582 
 583         /**
 584          * Tries to CAS right field to skip over apparent successor
 585          * succ.  Fails (forcing a retraversal by caller) if this node
 586          * is known to be deleted.
 587          * @param succ the expected current successor
 588          * @return true if successful
 589          */
 590         final boolean unlink(Index<K,V> succ) {
 591             return !indexesDeletedNode() && casRight(succ, succ.right);
 592         }
 593 
 594         // Unsafe mechanics
 595         private static final sun.misc.Unsafe UNSAFE;
 596         private static final long rightOffset;
 597         static {
 598             try {
 599                 UNSAFE = sun.misc.Unsafe.getUnsafe();
 600                 Class k = Index.class;
 601                 rightOffset = UNSAFE.objectFieldOffset
 602                     (k.getDeclaredField("right"));
 603             } catch (Exception e) {
 604                 throw new Error(e);
 605             }
 606         }
 607     }
 608 
 609     /* ---------------- Head nodes -------------- */
 610 
 611     /**
 612      * Nodes heading each level keep track of their level.
 613      */
 614     static final class HeadIndex<K,V> extends Index<K,V> {
 615         final int level;
 616         HeadIndex(Node<K,V> node, Index<K,V> down, Index<K,V> right, int level) {
 617             super(node, down, right);
 618             this.level = level;
 619         }
 620     }
 621 
 622     /* ---------------- Comparison utilities -------------- */
 623 
 624     /**
 625      * Represents a key with a comparator as a Comparable.
 626      *
 627      * Because most sorted collections seem to use natural ordering on
 628      * Comparables (Strings, Integers, etc), most internal methods are
 629      * geared to use them. This is generally faster than checking
 630      * per-comparison whether to use comparator or comparable because
 631      * it doesn‘t require a (Comparable) cast for each comparison.
 632      * (Optimizers can only sometimes remove such redundant checks
 633      * themselves.) When Comparators are used,
 634      * ComparableUsingComparators are created so that they act in the
 635      * same way as natural orderings. This penalizes use of
 636      * Comparators vs Comparables, which seems like the right
 637      * tradeoff.
 638      */
 639     static final class ComparableUsingComparator<K> implements Comparable<K> {
 640         final K actualKey;
 641         final Comparator<? super K> cmp;
 642         ComparableUsingComparator(K key, Comparator<? super K> cmp) {
 643             this.actualKey = key;
 644             this.cmp = cmp;
 645         }
 646         public int compareTo(K k2) {
 647             return cmp.compare(actualKey, k2);
 648         }
 649     }
 650 
 651     /**
 652      * If using comparator, return a ComparableUsingComparator, else
 653      * cast key as Comparable, which may cause ClassCastException,
 654      * which is propagated back to caller.
 655      */
 656     private Comparable<? super K> comparable(Object key)
 657             throws ClassCastException {
 658         if (key == null)
 659             throw new NullPointerException();
 660         if (comparator != null)
 661             return new ComparableUsingComparator<K>((K)key, comparator);
 662         else
 663             return (Comparable<? super K>)key;
 664     }
 665 
 666     /**
 667      * Compares using comparator or natural ordering. Used when the
 668      * ComparableUsingComparator approach doesn‘t apply.
 669      */
 670     int compare(K k1, K k2) throws ClassCastException {
 671         Comparator<? super K> cmp = comparator;
 672         if (cmp != null)
 673             return cmp.compare(k1, k2);
 674         else
 675             return ((Comparable<? super K>)k1).compareTo(k2);
 676     }
 677 
 678     /**
 679      * Returns true if given key greater than or equal to least and
 680      * strictly less than fence, bypassing either test if least or
 681      * fence are null. Needed mainly in submap operations.
 682      */
 683     boolean inHalfOpenRange(K key, K least, K fence) {
 684         if (key == null)
 685             throw new NullPointerException();
 686         return ((least == null || compare(key, least) >= 0) &&
 687                 (fence == null || compare(key, fence) <  0));
 688     }
 689 
 690     /**
 691      * Returns true if given key greater than or equal to least and less
 692      * or equal to fence. Needed mainly in submap operations.
 693      */
 694     boolean inOpenRange(K key, K least, K fence) {
 695         if (key == null)
 696             throw new NullPointerException();
 697         return ((least == null || compare(key, least) >= 0) &&
 698                 (fence == null || compare(key, fence) <= 0));
 699     }
 700 
 701     /* ---------------- Traversal -------------- */
 702 
 703     /**
 704      * Returns a base-level node with key strictly less than given key,
 705      * or the base-level header if there is no such node.  Also
 706      * unlinks indexes to deleted nodes found along the way.  Callers
 707      * rely on this side-effect of clearing indices to deleted nodes.
 708      * @param key the key
 709      * @return a predecessor of key
 710      */
 711     private Node<K,V> findPredecessor(Comparable<? super K> key) {
 712         if (key == null)
 713             throw new NullPointerException(); // don‘t postpone errors
 714         for (;;) {
 715             Index<K,V> q = head;
 716             Index<K,V> r = q.right;
 717             for (;;) {
 718                 if (r != null) {
 719                     Node<K,V> n = r.node;
 720                     K k = n.key;
 721                     if (n.value == null) {
 722                         if (!q.unlink(r))
 723                             break;           // restart
 724                         r = q.right;         // reread r
 725                         continue;
 726                     }
 727                     if (key.compareTo(k) > 0) {
 728                         q = r;
 729                         r = r.right;
 730                         continue;
 731                     }
 732                 }
 733                 Index<K,V> d = q.down;
 734                 if (d != null) {
 735                     q = d;
 736                     r = d.right;
 737                 } else
 738                     return q.node;
 739             }
 740         }
 741     }
 742 
 743     /**
 744      * Returns node holding key or null if no such, clearing out any
 745      * deleted nodes seen along the way.  Repeatedly traverses at
 746      * base-level looking for key starting at predecessor returned
 747      * from findPredecessor, processing base-level deletions as
 748      * encountered. Some callers rely on this side-effect of clearing
 749      * deleted nodes.
 750      *
 751      * Restarts occur, at traversal step centered on node n, if:
 752      *
 753      *   (1) After reading n‘s next field, n is no longer assumed
 754      *       predecessor b‘s current successor, which means that
 755      *       we don‘t have a consistent 3-node snapshot and so cannot
 756      *       unlink any subsequent deleted nodes encountered.
 757      *
 758      *   (2) n‘s value field is null, indicating n is deleted, in
 759      *       which case we help out an ongoing structural deletion
 760      *       before retrying.  Even though there are cases where such
 761      *       unlinking doesn‘t require restart, they aren‘t sorted out
 762      *       here because doing so would not usually outweigh cost of
 763      *       restarting.
 764      *
 765      *   (3) n is a marker or n‘s predecessor‘s value field is null,
 766      *       indicating (among other possibilities) that
 767      *       findPredecessor returned a deleted node. We can‘t unlink
 768      *       the node because we don‘t know its predecessor, so rely
 769      *       on another call to findPredecessor to notice and return
 770      *       some earlier predecessor, which it will do. This check is
 771      *       only strictly needed at beginning of loop, (and the
 772      *       b.value check isn‘t strictly needed at all) but is done
 773      *       each iteration to help avoid contention with other
 774      *       threads by callers that will fail to be able to change
 775      *       links, and so will retry anyway.
 776      *
 777      * The traversal loops in doPut, doRemove, and findNear all
 778      * include the same three kinds of checks. And specialized
 779      * versions appear in findFirst, and findLast and their
 780      * variants. They can‘t easily share code because each uses the
 781      * reads of fields held in locals occurring in the orders they
 782      * were performed.
 783      *
 784      * @param key the key
 785      * @return node holding key, or null if no such
 786      */
 787     private Node<K,V> findNode(Comparable<? super K> key) {
 788         for (;;) {
 789             Node<K,V> b = findPredecessor(key);
 790             Node<K,V> n = b.next;
 791             for (;;) {
 792                 if (n == null)
 793                     return null;
 794                 Node<K,V> f = n.next;
 795                 if (n != b.next)                // inconsistent read
 796                     break;
 797                 Object v = n.value;
 798                 if (v == null) {                // n is deleted
 799                     n.helpDelete(b, f);
 800                     break;
 801                 }
 802                 if (v == n || b.value == null)  // b is deleted
 803                     break;
 804                 int c = key.compareTo(n.key);
 805                 if (c == 0)
 806                     return n;
 807                 if (c < 0)
 808                     return null;
 809                 b = n;
 810                 n = f;
 811             }
 812         }
 813     }
 814 
 815     /**
 816      * Gets value for key using findNode.
 817      * @param okey the key
 818      * @return the value, or null if absent
 819      */
 820     private V doGet(Object okey) {
 821         Comparable<? super K> key = comparable(okey);
 822         /*
 823          * Loop needed here and elsewhere in case value field goes
 824          * null just as it is about to be returned, in which case we
 825          * lost a race with a deletion, so must retry.
 826          */
 827         for (;;) {
 828             Node<K,V> n = findNode(key);
 829             if (n == null)
 830                 return null;
 831             Object v = n.value;
 832             if (v != null)
 833                 return (V)v;
 834         }
 835     }
 836 
 837     /* ---------------- Insertion -------------- */
 838 
 839     /**
 840      * Main insertion method.  Adds element if not present, or
 841      * replaces value if present and onlyIfAbsent is false.
 842      * @param kkey the key
 843      * @param value  the value that must be associated with key
 844      * @param onlyIfAbsent if should not insert if already present
 845      * @return the old value, or null if newly inserted
 846      */
 847     private V doPut(K kkey, V value, boolean onlyIfAbsent) {
 848         Comparable<? super K> key = comparable(kkey);
 849         for (;;) {
 850             Node<K,V> b = findPredecessor(key);
 851             Node<K,V> n = b.next;
 852             for (;;) {
 853                 if (n != null) {
 854                     Node<K,V> f = n.next;
 855                     if (n != b.next)               // inconsistent read
 856                         break;
 857                     Object v = n.value;
 858                     if (v == null) {               // n is deleted
 859                         n.helpDelete(b, f);
 860                         break;
 861                     }
 862                     if (v == n || b.value == null) // b is deleted
 863                         break;
 864                     int c = key.compareTo(n.key);
 865                     if (c > 0) {
 866                         b = n;
 867                         n = f;
 868                         continue;
 869                     }
 870                     if (c == 0) {
 871                         if (onlyIfAbsent || n.casValue(v, value))
 872                             return (V)v;
 873                         else
 874                             break; // restart if lost race to replace value
 875                     }
 876                     // else c < 0; fall through
 877                 }
 878 
 879                 Node<K,V> z = new Node<K,V>(kkey, value, n);
 880                 if (!b.casNext(n, z))
 881                     break;         // restart if lost race to append to b
 882                 int level = randomLevel();
 883                 if (level > 0)
 884                     insertIndex(z, level);
 885                 return null;
 886             }
 887         }
 888     }
 889 
 890     /**
 891      * Returns a random level for inserting a new node.
 892      * Hardwired to k=1, p=0.5, max 31 (see above and
 893      * Pugh‘s "Skip List Cookbook", sec 3.4).
 894      *
 895      * This uses the simplest of the generators described in George
 896      * Marsaglia‘s "Xorshift RNGs" paper.  This is not a high-quality
 897      * generator but is acceptable here.
 898      */
 899     private int randomLevel() {
 900         int x = randomSeed;
 901         x ^= x << 13;
 902         x ^= x >>> 17;
 903         randomSeed = x ^= x << 5;
 904         if ((x & 0x80000001) != 0) // test highest and lowest bits
 905             return 0;
 906         int level = 1;
 907         while (((x >>>= 1) & 1) != 0) ++level;
 908         return level;
 909     }
 910 
 911     /**
 912      * Creates and adds index nodes for the given node.
 913      * @param z the node
 914      * @param level the level of the index
 915      */
 916     private void insertIndex(Node<K,V> z, int level) {
 917         HeadIndex<K,V> h = head;
 918         int max = h.level;
 919 
 920         if (level <= max) {
 921             Index<K,V> idx = null;
 922             for (int i = 1; i <= level; ++i)
 923                 idx = new Index<K,V>(z, idx, null);
 924             addIndex(idx, h, level);
 925 
 926         } else { // Add a new level
 927             /*
 928              * To reduce interference by other threads checking for
 929              * empty levels in tryReduceLevel, new levels are added
 930              * with initialized right pointers. Which in turn requires
 931              * keeping levels in an array to access them while
 932              * creating new head index nodes from the opposite
 933              * direction.
 934              */
 935             level = max + 1;
 936             Index<K,V>[] idxs = (Index<K,V>[])new Index[level+1];
 937             Index<K,V> idx = null;
 938             for (int i = 1; i <= level; ++i)
 939                 idxs[i] = idx = new Index<K,V>(z, idx, null);
 940 
 941             HeadIndex<K,V> oldh;
 942             int k;
 943             for (;;) {
 944                 oldh = head;
 945                 int oldLevel = oldh.level;
 946                 if (level <= oldLevel) { // lost race to add level
 947                     k = level;
 948                     break;
 949                 }
 950                 HeadIndex<K,V> newh = oldh;
 951                 Node<K,V> oldbase = oldh.node;
 952                 for (int j = oldLevel+1; j <= level; ++j)
 953                     newh = new HeadIndex<K,V>(oldbase, newh, idxs[j], j);
 954                 if (casHead(oldh, newh)) {
 955                     k = oldLevel;
 956                     break;
 957                 }
 958             }
 959             addIndex(idxs[k], oldh, k);
 960         }
 961     }
 962 
 963     /**
 964      * Adds given index nodes from given level down to 1.
 965      * @param idx the topmost index node being inserted
 966      * @param h the value of head to use to insert. This must be
 967      * snapshotted by callers to provide correct insertion level
 968      * @param indexLevel the level of the index
 969      */
 970     private void addIndex(Index<K,V> idx, HeadIndex<K,V> h, int indexLevel) {
 971         // Track next level to insert in case of retries
 972         int insertionLevel = indexLevel;
 973         Comparable<? super K> key = comparable(idx.node.key);
 974         if (key == null) throw new NullPointerException();
 975 
 976         // Similar to findPredecessor, but adding index nodes along
 977         // path to key.
 978         for (;;) {
 979             int j = h.level;
 980             Index<K,V> q = h;
 981             Index<K,V> r = q.right;
 982             Index<K,V> t = idx;
 983             for (;;) {
 984                 if (r != null) {
 985                     Node<K,V> n = r.node;
 986                     // compare before deletion check avoids needing recheck
 987                     int c = key.compareTo(n.key);
 988                     if (n.value == null) {
 989                         if (!q.unlink(r))
 990                             break;
 991                         r = q.right;
 992                         continue;
 993                     }
 994                     if (c > 0) {
 995                         q = r;
 996                         r = r.right;
 997                         continue;
 998                     }
 999                 }
1000 
1001                 if (j == insertionLevel) {
1002                     // Don‘t insert index if node already deleted
1003                     if (t.indexesDeletedNode()) {
1004                         findNode(key); // cleans up
1005                         return;
1006                     }
1007                     if (!q.link(r, t))
1008                         break; // restart
1009                     if (--insertionLevel == 0) {
1010                         // need final deletion check before return
1011                         if (t.indexesDeletedNode())
1012                             findNode(key);
1013                         return;
1014                     }
1015                 }
1016 
1017                 if (--j >= insertionLevel && j < indexLevel)
1018                     t = t.down;
1019                 q = q.down;
1020                 r = q.right;
1021             }
1022         }
1023     }
1024 
1025     /* ---------------- Deletion -------------- */
1026 
1027     /**
1028      * Main deletion method. Locates node, nulls value, appends a
1029      * deletion marker, unlinks predecessor, removes associated index
1030      * nodes, and possibly reduces head index level.
1031      *
1032      * Index nodes are cleared out simply by calling findPredecessor.
1033      * which unlinks indexes to deleted nodes found along path to key,
1034      * which will include the indexes to this node.  This is done
1035      * unconditionally. We can‘t check beforehand whether there are
1036      * index nodes because it might be the case that some or all
1037      * indexes hadn‘t been inserted yet for this node during initial
1038      * search for it, and we‘d like to ensure lack of garbage
1039      * retention, so must call to be sure.
1040      *
1041      * @param okey the key
1042      * @param value if non-null, the value that must be
1043      * associated with key
1044      * @return the node, or null if not found
1045      */
1046     final V doRemove(Object okey, Object value) {
1047         Comparable<? super K> key = comparable(okey);
1048         for (;;) {
1049             Node<K,V> b = findPredecessor(key);
1050             Node<K,V> n = b.next;
1051             for (;;) {
1052                 if (n == null)
1053                     return null;
1054                 Node<K,V> f = n.next;
1055                 if (n != b.next)                    // inconsistent read
1056                     break;
1057                 Object v = n.value;
1058                 if (v == null) {                    // n is deleted
1059                     n.helpDelete(b, f);
1060                     break;
1061                 }
1062                 if (v == n || b.value == null)      // b is deleted
1063                     break;
1064                 int c = key.compareTo(n.key);
1065                 if (c < 0)
1066                     return null;
1067                 if (c > 0) {
1068                     b = n;
1069                     n = f;
1070                     continue;
1071                 }
1072                 if (value != null && !value.equals(v))
1073                     return null;
1074                 if (!n.casValue(v, null))
1075                     break;
1076                 if (!n.appendMarker(f) || !b.casNext(n, f))
1077                     findNode(key);                  // Retry via findNode
1078                 else {
1079                     findPredecessor(key);           // Clean index
1080                     if (head.right == null)
1081                         tryReduceLevel();
1082                 }
1083                 return (V)v;
1084             }
1085         }
1086     }
1087 
1088     /**
1089      * Possibly reduce head level if it has no nodes.  This method can
1090      * (rarely) make mistakes, in which case levels can disappear even
1091      * though they are about to contain index nodes. This impacts
1092      * performance, not correctness.  To minimize mistakes as well as
1093      * to reduce hysteresis, the level is reduced by one only if the
1094      * topmost three levels look empty. Also, if the removed level
1095      * looks non-empty after CAS, we try to change it back quick
1096      * before anyone notices our mistake! (This trick works pretty
1097      * well because this method will practically never make mistakes
1098      * unless current thread stalls immediately before first CAS, in
1099      * which case it is very unlikely to stall again immediately
1100      * afterwards, so will recover.)
1101      *
1102      * We put up with all this rather than just let levels grow
1103      * because otherwise, even a small map that has undergone a large
1104      * number of insertions and removals will have a lot of levels,
1105      * slowing down access more than would an occasional unwanted
1106      * reduction.
1107      */
1108     private void tryReduceLevel() {
1109         HeadIndex<K,V> h = head;
1110         HeadIndex<K,V> d;
1111         HeadIndex<K,V> e;
1112         if (h.level > 3 &&
1113             (d = (HeadIndex<K,V>)h.down) != null &&
1114             (e = (HeadIndex<K,V>)d.down) != null &&
1115             e.right == null &&
1116             d.right == null &&
1117             h.right == null &&
1118             casHead(h, d) && // try to set
1119             h.right != null) // recheck
1120             casHead(d, h);   // try to backout
1121     }
1122 
1123     /* ---------------- Finding and removing first element -------------- */
1124 
1125     /**
1126      * Specialized variant of findNode to get first valid node.
1127      * @return first node or null if empty
1128      */
1129     Node<K,V> findFirst() {
1130         for (;;) {
1131             Node<K,V> b = head.node;
1132             Node<K,V> n = b.next;
1133             if (n == null)
1134                 return null;
1135             if (n.value != null)
1136                 return n;
1137             n.helpDelete(b, n.next);
1138         }
1139     }
1140 
1141     /**
1142      * Removes first entry; returns its snapshot.
1143      * @return null if empty, else snapshot of first entry
1144      */
1145     Map.Entry<K,V> doRemoveFirstEntry() {
1146         for (;;) {
1147             Node<K,V> b = head.node;
1148             Node<K,V> n = b.next;
1149             if (n == null)
1150                 return null;
1151             Node<K,V> f = n.next;
1152             if (n != b.next)
1153                 continue;
1154             Object v = n.value;
1155             if (v == null) {
1156                 n.helpDelete(b, f);
1157                 continue;
1158             }
1159             if (!n.casValue(v, null))
1160                 continue;
1161             if (!n.appendMarker(f) || !b.casNext(n, f))
1162                 findFirst(); // retry
1163             clearIndexToFirst();
1164             return new AbstractMap.SimpleImmutableEntry<K,V>(n.key, (V)v);
1165         }
1166     }
1167 
1168     /**
1169      * Clears out index nodes associated with deleted first entry.
1170      */
1171     private void clearIndexToFirst() {
1172         for (;;) {
1173             Index<K,V> q = head;
1174             for (;;) {
1175                 Index<K,V> r = q.right;
1176                 if (r != null && r.indexesDeletedNode() && !q.unlink(r))
1177                     break;
1178                 if ((q = q.down) == null) {
1179                     if (head.right == null)
1180                         tryReduceLevel();
1181                     return;
1182                 }
1183             }
1184         }
1185     }
1186 
1187 
1188     /* ---------------- Finding and removing last element -------------- */
1189 
1190     /**
1191      * Specialized version of find to get last valid node.
1192      * @return last node or null if empty
1193      */
1194     Node<K,V> findLast() {
1195         /*
1196          * findPredecessor can‘t be used to traverse index level
1197          * because this doesn‘t use comparisons.  So traversals of
1198          * both levels are folded together.
1199          */
1200         Index<K,V> q = head;
1201         for (;;) {
1202             Index<K,V> d, r;
1203             if ((r = q.right) != null) {
1204                 if (r.indexesDeletedNode()) {
1205                     q.unlink(r);
1206                     q = head; // restart
1207                 }
1208                 else
1209                     q = r;
1210             } else if ((d = q.down) != null) {
1211                 q = d;
1212             } else {
1213                 Node<K,V> b = q.node;
1214                 Node<K,V> n = b.next;
1215                 for (;;) {
1216                     if (n == null)
1217                         return b.isBaseHeader() ? null : b;
1218                     Node<K,V> f = n.next;            // inconsistent read
1219                     if (n != b.next)
1220                         break;
1221                     Object v = n.value;
1222                     if (v == null) {                 // n is deleted
1223                         n.helpDelete(b, f);
1224                         break;
1225                     }
1226                     if (v == n || b.value == null)   // b is deleted
1227                         break;
1228                     b = n;
1229                     n = f;
1230                 }
1231                 q = head; // restart
1232             }
1233         }
1234     }
1235 
1236     /**
1237      * Specialized variant of findPredecessor to get predecessor of last
1238      * valid node.  Needed when removing the last entry.  It is possible
1239      * that all successors of returned node will have been deleted upon
1240      * return, in which case this method can be retried.
1241      * @return likely predecessor of last node
1242      */
1243     private Node<K,V> findPredecessorOfLast() {
1244         for (;;) {
1245             Index<K,V> q = head;
1246             for (;;) {
1247                 Index<K,V> d, r;
1248                 if ((r = q.right) != null) {
1249                     if (r.indexesDeletedNode()) {
1250                         q.unlink(r);
1251                         break;    // must restart
1252                     }
1253                     // proceed as far across as possible without overshooting
1254                     if (r.node.next != null) {
1255                         q = r;
1256                         continue;
1257                     }
1258                 }
1259                 if ((d = q.down) != null)
1260                     q = d;
1261                 else
1262                     return q.node;
1263             }
1264         }
1265     }
1266 
1267     /**
1268      * Removes last entry; returns its snapshot.
1269      * Specialized variant of doRemove.
1270      * @return null if empty, else snapshot of last entry
1271      */
1272     Map.Entry<K,V> doRemoveLastEntry() {
1273         for (;;) {
1274             Node<K,V> b = findPredecessorOfLast();
1275             Node<K,V> n = b.next;
1276             if (n == null) {
1277                 if (b.isBaseHeader())               // empty
1278                     return null;
1279                 else
1280                     continue; // all b‘s successors are deleted; retry
1281             }
1282             for (;;) {
1283                 Node<K,V> f = n.next;
1284                 if (n != b.next)                    // inconsistent read
1285                     break;
1286                 Object v = n.value;
1287                 if (v == null) {                    // n is deleted
1288                     n.helpDelete(b, f);
1289                     break;
1290                 }
1291                 if (v == n || b.value == null)      // b is deleted
1292                     break;
1293                 if (f != null) {
1294                     b = n;
1295                     n = f;
1296                     continue;
1297                 }
1298                 if (!n.casValue(v, null))
1299                     break;
1300                 K key = n.key;
1301                 Comparable<? super K> ck = comparable(key);
1302                 if (!n.appendMarker(f) || !b.casNext(n, f))
1303                     findNode(ck);                  // Retry via findNode
1304                 else {
1305                     findPredecessor(ck);           // Clean index
1306                     if (head.right == null)
1307                         tryReduceLevel();
1308                 }
1309                 return new AbstractMap.SimpleImmutableEntry<K,V>(key, (V)v);
1310             }
1311         }
1312     }
1313 
1314     /* ---------------- Relational operations -------------- */
1315 
1316     // Control values OR‘ed as arguments to findNear
1317 
1318     private static final int EQ = 1;
1319     private static final int LT = 2;
1320     private static final int GT = 0; // Actually checked as !LT
1321 
1322     /**
1323      * Utility for ceiling, floor, lower, higher methods.
1324      * @param kkey the key
1325      * @param rel the relation -- OR‘ed combination of EQ, LT, GT
1326      * @return nearest node fitting relation, or null if no such
1327      */
1328     Node<K,V> findNear(K kkey, int rel) {
1329         Comparable<? super K> key = comparable(kkey);
1330         for (;;) {
1331             Node<K,V> b = findPredecessor(key);
1332             Node<K,V> n = b.next;
1333             for (;;) {
1334                 if (n == null)
1335                     return ((rel & LT) == 0 || b.isBaseHeader()) ? null : b;
1336                 Node<K,V> f = n.next;
1337                 if (n != b.next)                  // inconsistent read
1338                     break;
1339                 Object v = n.value;
1340                 if (v == null) {                  // n is deleted
1341                     n.helpDelete(b, f);
1342                     break;
1343                 }
1344                 if (v == n || b.value == null)    // b is deleted
1345                     break;
1346                 int c = key.compareTo(n.key);
1347                 if ((c == 0 && (rel & EQ) != 0) ||
1348                     (c <  0 && (rel & LT) == 0))
1349                     return n;
1350                 if ( c <= 0 && (rel & LT) != 0)
1351                     return b.isBaseHeader() ? null : b;
1352                 b = n;
1353                 n = f;
1354             }
1355         }
1356     }
1357 
1358     /**
1359      * Returns SimpleImmutableEntry for results of findNear.
1360      * @param key the key
1361      * @param rel the relation -- OR‘ed combination of EQ, LT, GT
1362      * @return Entry fitting relation, or null if no such
1363      */
1364     AbstractMap.SimpleImmutableEntry<K,V> getNear(K key, int rel) {
1365         for (;;) {
1366             Node<K,V> n = findNear(key, rel);
1367             if (n == null)
1368                 return null;
1369             AbstractMap.SimpleImmutableEntry<K,V> e = n.createSnapshot();
1370             if (e != null)
1371                 return e;
1372         }
1373     }
1374 
1375 
1376     /* ---------------- Constructors -------------- */
1377 
1378     /**
1379      * Constructs a new, empty map, sorted according to the
1380      * {@linkplain Comparable natural ordering} of the keys.
1381      */
1382     public ConcurrentSkipListMap() {
1383         this.comparator = null;
1384         initialize();
1385     }
1386 
1387     /**
1388      * Constructs a new, empty map, sorted according to the specified
1389      * comparator.
1390      *
1391      * @param comparator the comparator that will be used to order this map.
1392      *        If <tt>null</tt>, the {@linkplain Comparable natural
1393      *        ordering} of the keys will be used.
1394      */
1395     public ConcurrentSkipListMap(Comparator<? super K> comparator) {
1396         this.comparator = comparator;
1397         initialize();
1398     }
1399 
1400     /**
1401      * Constructs a new map containing the same mappings as the given map,
1402      * sorted according to the {@linkplain Comparable natural ordering} of
1403      * the keys.
1404      *
1405      * @param  m the map whose mappings are to be placed in this map
1406      * @throws ClassCastException if the keys in <tt>m</tt> are not
1407      *         {@link Comparable}, or are not mutually comparable
1408      * @throws NullPointerException if the specified map or any of its keys
1409      *         or values are null
1410      */
1411     public ConcurrentSkipListMap(Map<? extends K, ? extends V> m) {
1412         this.comparator = null;
1413         initialize();
1414         putAll(m);
1415     }
1416 
1417     /**
1418      * Constructs a new map containing the same mappings and using the
1419      * same ordering as the specified sorted map.
1420      *
1421      * @param m the sorted map whose mappings are to be placed in this
1422      *        map, and whose comparator is to be used to sort this map
1423      * @throws NullPointerException if the specified sorted map or any of
1424      *         its keys or values are null
1425      */
1426     public ConcurrentSkipListMap(SortedMap<K, ? extends V> m) {
1427         this.comparator = m.comparator();
1428         initialize();
1429         buildFromSorted(m);
1430     }
1431 
1432     /**
1433      * Returns a shallow copy of this <tt>ConcurrentSkipListMap</tt>
1434      * instance. (The keys and values themselves are not cloned.)
1435      *
1436      * @return a shallow copy of this map
1437      */
1438     public ConcurrentSkipListMap<K,V> clone() {
1439         ConcurrentSkipListMap<K,V> clone = null;
1440         try {
1441             clone = (ConcurrentSkipListMap<K,V>) super.clone();
1442         } catch (CloneNotSupportedException e) {
1443             throw new InternalError();
1444         }
1445 
1446         clone.initialize();
1447         clone.buildFromSorted(this);
1448         return clone;
1449     }
1450 
1451     /**
1452      * Streamlined bulk insertion to initialize from elements of
1453      * given sorted map.  Call only from constructor or clone
1454      * method.
1455      */
1456     private void buildFromSorted(SortedMap<K, ? extends V> map) {
1457         if (map == null)
1458             throw new NullPointerException();
1459 
1460         HeadIndex<K,V> h = head;
1461         Node<K,V> basepred = h.node;
1462 
1463         // Track the current rightmost node at each level. Uses an
1464         // ArrayList to avoid committing to initial or maximum level.
1465         ArrayList<Index<K,V>> preds = new ArrayList<Index<K,V>>();
1466 
1467         // initialize
1468         for (int i = 0; i <= h.level; ++i)
1469             preds.add(null);
1470         Index<K,V> q = h;
1471         for (int i = h.level; i > 0; --i) {
1472             preds.set(i, q);
1473             q = q.down;
1474         }
1475 
1476         Iterator<? extends Map.Entry<? extends K, ? extends V>> it =
1477             map.entrySet().iterator();
1478         while (it.hasNext()) {
1479             Map.Entry<? extends K, ? extends V> e = it.next();
1480             int j = randomLevel();
1481             if (j > h.level) j = h.level + 1;
1482             K k = e.getKey();
1483             V v = e.getValue();
1484             if (k == null || v == null)
1485                 throw new NullPointerException();
1486             Node<K,V> z = new Node<K,V>(k, v, null);
1487             basepred.next = z;
1488             basepred = z;
1489             if (j > 0) {
1490                 Index<K,V> idx = null;
1491                 for (int i = 1; i <= j; ++i) {
1492                     idx = new Index<K,V>(z, idx, null);
1493                     if (i > h.level)
1494                         h = new HeadIndex<K,V>(h.node, h, idx, i);
1495 
1496                     if (i < preds.size()) {
1497                         preds.get(i).right = idx;
1498                         preds.set(i, idx);
1499                     } else
1500                         preds.add(idx);
1501                 }
1502             }
1503         }
1504         head = h;
1505     }
1506 
1507     /* ---------------- Serialization -------------- */
1508 
1509     /**
1510      * Save the state of this map to a stream.
1511      *
1512      * @serialData The key (Object) and value (Object) for each
1513      * key-value mapping represented by the map, followed by
1514      * <tt>null</tt>. The key-value mappings are emitted in key-order
1515      * (as determined by the Comparator, or by the keys‘ natural
1516      * ordering if no Comparator).
1517      */
1518     private void writeObject(java.io.ObjectOutputStream s)
1519         throws java.io.IOException {
1520         // Write out the Comparator and any hidden stuff
1521         s.defaultWriteObject();
1522 
1523         // Write out keys and values (alternating)
1524         for (Node<K,V> n = findFirst(); n != null; n = n.next) {
1525             V v = n.getValidValue();
1526             if (v != null) {
1527                 s.writeObject(n.key);
1528                 s.writeObject(v);
1529             }
1530         }
1531         s.writeObject(null);
1532     }
1533 
1534     /**
1535      * Reconstitute the map from a stream.
1536      */
1537     private void readObject(final java.io.ObjectInputStream s)
1538         throws java.io.IOException, ClassNotFoundException {
1539         // Read in the Comparator and any hidden stuff
1540         s.defaultReadObject();
1541         // Reset transients
1542         initialize();
1543 
1544         /*
1545          * This is nearly identical to buildFromSorted, but is
1546          * distinct because readObject calls can‘t be nicely adapted
1547          * as the kind of iterator needed by buildFromSorted. (They
1548          * can be, but doing so requires type cheats and/or creation
1549          * of adaptor classes.) It is simpler to just adapt the code.
1550          */
1551 
1552         HeadIndex<K,V> h = head;
1553         Node<K,V> basepred = h.node;
1554         ArrayList<Index<K,V>> preds = new ArrayList<Index<K,V>>();
1555         for (int i = 0; i <= h.level; ++i)
1556             preds.add(null);
1557         Index<K,V> q = h;
1558         for (int i = h.level; i > 0; --i) {
1559             preds.set(i, q);
1560             q = q.down;
1561         }
1562 
1563         for (;;) {
1564             Object k = s.readObject();
1565             if (k == null)
1566                 break;
1567             Object v = s.readObject();
1568             if (v == null)
1569                 throw new NullPointerException();
1570             K key = (K) k;
1571             V val = (V) v;
1572             int j = randomLevel();
1573             if (j > h.level) j = h.level + 1;
1574             Node<K,V> z = new Node<K,V>(key, val, null);
1575             basepred.next = z;
1576             basepred = z;
1577             if (j > 0) {
1578                 Index<K,V> idx = null;
1579                 for (int i = 1; i <= j; ++i) {
1580                     idx = new Index<K,V>(z, idx, null);
1581                     if (i > h.level)
1582                         h = new HeadIndex<K,V>(h.node, h, idx, i);
1583 
1584                     if (i < preds.size()) {
1585                         preds.get(i).right = idx;
1586                         preds.set(i, idx);
1587                     } else
1588                         preds.add(idx);
1589                 }
1590             }
1591         }
1592         head = h;
1593     }
1594 
1595     /* ------ Map API methods ------ */
1596 
1597     /**
1598      * Returns <tt>true</tt> if this map contains a mapping for the specified
1599      * key.
1600      *
1601      * @param key key whose presence in this map is to be tested
1602      * @return <tt>true</tt> if this map contains a mapping for the specified key
1603      * @throws ClassCastException if the specified key cannot be compared
1604      *         with the keys currently in the map
1605      * @throws NullPointerException if the specified key is null
1606      */
1607     public boolean containsKey(Object key) {
1608         return doGet(key) != null;
1609     }
1610 
1611     /**
1612      * Returns the value to which the specified key is mapped,
1613      * or {@code null} if this map contains no mapping for the key.
1614      *
1615      * <p>More formally, if this map contains a mapping from a key
1616      * {@code k} to a value {@code v} such that {@code key} compares
1617      * equal to {@code k} according to the map‘s ordering, then this
1618      * method returns {@code v}; otherwise it returns {@code null}.
1619      * (There can be at most one such mapping.)
1620      *
1621      * @throws ClassCastException if the specified key cannot be compared
1622      *         with the keys currently in the map
1623      * @throws NullPointerException if the specified key is null
1624      */
1625     public V get(Object key) {
1626         return doGet(key);
1627     }
1628 
1629     /**
1630      * Associates the specified value with the specified key in this map.
1631      * If the map previously contained a mapping for the key, the old
1632      * value is replaced.
1633      *
1634      * @param key key with which the specified value is to be associated
1635      * @param value value to be associated with the specified key
1636      * @return the previous value associated with the specified key, or
1637      *         <tt>null</tt> if there was no mapping for the key
1638      * @throws ClassCastException if the specified key cannot be compared
1639      *         with the keys currently in the map
1640      * @throws NullPointerException if the specified key or value is null
1641      */
1642     public V put(K key, V value) {
1643         if (value == null)
1644             throw new NullPointerException();
1645         return doPut(key, value, false);
1646     }
1647 
1648     /**
1649      * Removes the mapping for the specified key from this map if present.
1650      *
1651      * @param  key key for which mapping should be removed
1652      * @return the previous value associated with the specified key, or
1653      *         <tt>null</tt> if there was no mapping for the key
1654      * @throws ClassCastException if the specified key cannot be compared
1655      *         with the keys currently in the map
1656      * @throws NullPointerException if the specified key is null
1657      */
1658     public V remove(Object key) {
1659         return doRemove(key, null);
1660     }
1661 
1662     /**
1663      * Returns <tt>true</tt> if this map maps one or more keys to the
1664      * specified value.  This operation requires time linear in the
1665      * map size. Additionally, it is possible for the map to change
1666      * during execution of this method, in which case the returned
1667      * result may be inaccurate.
1668      *
1669      * @param value value whose presence in this map is to be tested
1670      * @return <tt>true</tt> if a mapping to <tt>value</tt> exists;
1671      *         <tt>false</tt> otherwise
1672      * @throws NullPointerException if the specified value is null
1673      */
1674     public boolean containsValue(Object value) {
1675         if (value == null)
1676             throw new NullPointerException();
1677         for (Node<K,V> n = findFirst(); n != null; n = n.next) {
1678             V v = n.getValidValue();
1679             if (v != null && value.equals(v))
1680                 return true;
1681         }
1682         return false;
1683     }
1684 
1685     /**
1686      * Returns the number of key-value mappings in this map.  If this map
1687      * contains more than <tt>Integer.MAX_VALUE</tt> elements, it
1688      * returns <tt>Integer.MAX_VALUE</tt>.
1689      *
1690      * <p>Beware that, unlike in most collections, this method is
1691      * <em>NOT</em> a constant-time operation. Because of the
1692      * asynchronous nature of these maps, determining the current
1693      * number of elements requires traversing them all to count them.
1694      * Additionally, it is possible for the size to change during
1695      * execution of this method, in which case the returned result
1696      * will be inaccurate. Thus, this method is typically not very
1697      * useful in concurrent applications.
1698      *
1699      * @return the number of elements in this map
1700      */
1701     public int size() {
1702         long count = 0;
1703         for (Node<K,V> n = findFirst(); n != null; n = n.next) {
1704             if (n.getValidValue() != null)
1705                 ++count;
1706         }
1707         return (count >= Integer.MAX_VALUE) ? Integer.MAX_VALUE : (int) count;
1708     }
1709 
1710     /**
1711      * Returns <tt>true</tt> if this map contains no key-value mappings.
1712      * @return <tt>true</tt> if this map contains no key-value mappings
1713      */
1714     public boolean isEmpty() {
1715         return findFirst() == null;
1716     }
1717 
1718     /**
1719      * Removes all of the mappings from this map.
1720      */
1721     public void clear() {
1722         initialize();
1723     }
1724 
1725     /* ---------------- View methods -------------- */
1726 
1727     /*
1728      * Note: Lazy initialization works for views because view classes
1729      * are stateless/immutable so it doesn‘t matter wrt correctness if
1730      * more than one is created (which will only rarely happen).  Even
1731      * so, the following idiom conservatively ensures that the method
1732      * returns the one it created if it does so, not one created by
1733      * another racing thread.
1734      */
1735 
1736     /**
1737      * Returns a {@link NavigableSet} view of the keys contained in this map.
1738      * The set‘s iterator returns the keys in ascending order.
1739      * The set is backed by the map, so changes to the map are
1740      * reflected in the set, and vice-versa.  The set supports element
1741      * removal, which removes the corresponding mapping from the map,
1742      * via the {@code Iterator.remove}, {@code Set.remove},
1743      * {@code removeAll}, {@code retainAll}, and {@code clear}
1744      * operations.  It does not support the {@code add} or {@code addAll}
1745      * operations.
1746      *
1747      * <p>The view‘s {@code iterator} is a "weakly consistent" iterator
1748      * that will never throw {@link ConcurrentModificationException},
1749      * and guarantees to traverse elements as they existed upon
1750      * construction of the iterator, and may (but is not guaranteed to)
1751      * reflect any modifications subsequent to construction.
1752      *
1753      * <p>This method is equivalent to method {@code navigableKeySet}.
1754      *
1755      * @return a navigable set view of the keys in this map
1756      */
1757     public NavigableSet<K> keySet() {
1758         KeySet ks = keySet;
1759         return (ks != null) ? ks : (keySet = new KeySet(this));
1760     }
1761 
1762     public NavigableSet<K> navigableKeySet() {
1763         KeySet ks = keySet;
1764         return (ks != null) ? ks : (keySet = new KeySet(this));
1765     }
1766 
1767     /**
1768      * Returns a {@link Collection} view of the values contained in this map.
1769      * The collection‘s iterator returns the values in ascending order
1770      * of the corresponding keys.
1771      * The collection is backed by the map, so changes to the map are
1772      * reflected in the collection, and vice-versa.  The collection
1773      * supports element removal, which removes the corresponding
1774      * mapping from the map, via the <tt>Iterator.remove</tt>,
1775      * <tt>Collection.remove</tt>, <tt>removeAll</tt>,
1776      * <tt>retainAll</tt> and <tt>clear</tt> operations.  It does not
1777      * support the <tt>add</tt> or <tt>addAll</tt> operations.
1778      *
1779      * <p>The view‘s <tt>iterator</tt> is a "weakly consistent" iterator
1780      * that will never throw {@link ConcurrentModificationException},
1781      * and guarantees to traverse elements as they existed upon
1782      * construction of the iterator, and may (but is not guaranteed to)
1783      * reflect any modifications subsequent to construction.
1784      */
1785     public Collection<V> values() {
1786         Values vs = values;
1787         return (vs != null) ? vs : (values = new Values(this));
1788     }
1789 
1790     /**
1791      * Returns a {@link Set} view of the mappings contained in this map.
1792      * The set‘s iterator returns the entries in ascending key order.
1793      * The set is backed by the map, so changes to the map are
1794      * reflected in the set, and vice-versa.  The set supports element
1795      * removal, which removes the corresponding mapping from the map,
1796      * via the <tt>Iterator.remove</tt>, <tt>Set.remove</tt>,
1797      * <tt>removeAll</tt>, <tt>retainAll</tt> and <tt>clear</tt>
1798      * operations.  It does not support the <tt>add</tt> or
1799      * <tt>addAll</tt> operations.
1800      *
1801      * <p>The view‘s <tt>iterator</tt> is a "weakly consistent" iterator
1802      * that will never throw {@link ConcurrentModificationException},
1803      * and guarantees to traverse elements as they existed upon
1804      * construction of the iterator, and may (but is not guaranteed to)
1805      * reflect any modifications subsequent to construction.
1806      *
1807      * <p>The <tt>Map.Entry</tt> elements returned by
1808      * <tt>iterator.next()</tt> do <em>not</em> support the
1809      * <tt>setValue</tt> operation.
1810      *
1811      * @return a set view of the mappings contained in this map,
1812      *         sorted in ascending key order
1813      */
1814     public Set<Map.Entry<K,V>> entrySet() {
1815         EntrySet es = entrySet;
1816         return (es != null) ? es : (entrySet = new EntrySet(this));
1817     }
1818 
1819     public ConcurrentNavigableMap<K,V> descendingMap() {
1820         ConcurrentNavigableMap<K,V> dm = descendingMap;
1821         return (dm != null) ? dm : (descendingMap = new SubMap<K,V>
1822                                     (this, null, false, null, false, true));
1823     }
1824 
1825     public NavigableSet<K> descendingKeySet() {
1826         return descendingMap().navigableKeySet();
1827     }
1828 
1829     /* ---------------- AbstractMap Overrides -------------- */
1830 
1831     /**
1832      * Compares the specified object with this map for equality.
1833      * Returns <tt>true</tt> if the given object is also a map and the
1834      * two maps represent the same mappings.  More formally, two maps
1835      * <tt>m1</tt> and <tt>m2</tt> represent the same mappings if
1836      * <tt>m1.entrySet().equals(m2.entrySet())</tt>.  This
1837      * operation may return misleading results if either map is
1838      * concurrently modified during execution of this method.
1839      *
1840      * @param o object to be compared for equality with this map
1841      * @return <tt>true</tt> if the specified object is equal to this map
1842      */
1843     public boolean equals(Object o) {
1844         if (o == this)
1845             return true;
1846         if (!(o instanceof Map))
1847             return false;
1848         Map<?,?> m = (Map<?,?>) o;
1849         try {
1850             for (Map.Entry<K,V> e : this.entrySet())
1851                 if (! e.getValue().equals(m.get(e.getKey())))
1852                     return false;
1853             for (Map.Entry<?,?> e : m.entrySet()) {
1854                 Object k = e.getKey();
1855                 Object v = e.getValue();
1856                 if (k == null || v == null || !v.equals(get(k)))
1857                     return false;
1858             }
1859             return true;
1860         } catch (ClassCastException unused) {
1861             return false;
1862         } catch (NullPointerException unused) {
1863             return false;
1864         }
1865     }
1866 
1867     /* ------ ConcurrentMap API methods ------ */
1868 
1869     /**
1870      * {@inheritDoc}
1871      *
1872      * @return the previous value associated with the specified key,
1873      *         or <tt>null</tt> if there was no mapping for the key
1874      * @throws ClassCastException if the specified key cannot be compared
1875      *         with the keys currently in the map
1876      * @throws NullPointerException if the specified key or value is null
1877      */
1878     public V putIfAbsent(K key, V value) {
1879         if (value == null)
1880             throw new NullPointerException();
1881         return doPut(key, value, true);
1882     }
1883 
1884     /**
1885      * {@inheritDoc}
1886      *
1887      * @throws ClassCastException if the specified key cannot be compared
1888      *         with the keys currently in the map
1889      * @throws NullPointerException if the specified key is null
1890      */
1891     public boolean remove(Object key, Object value) {
1892         if (key == null)
1893             throw new NullPointerException();
1894         if (value == null)
1895             return false;
1896         return doRemove(key, value) != null;
1897     }
1898 
1899     /**
1900      * {@inheritDoc}
1901      *
1902      * @throws ClassCastException if the specified key cannot be compared
1903      *         with the keys currently in the map
1904      * @throws NullPointerException if any of the arguments are null
1905      */
1906     public boolean replace(K key, V oldValue, V newValue) {
1907         if (oldValue == null || newValue == null)
1908             throw new NullPointerException();
1909         Comparable<? super K> k = comparable(key);
1910         for (;;) {
1911             Node<K,V> n = findNode(k);
1912             if (n == null)
1913                 return false;
1914             Object v = n.value;
1915             if (v != null) {
1916                 if (!oldValue.equals(v))
1917                     return false;
1918                 if (n.casValue(v, newValue))
1919                     return true;
1920             }
1921         }
1922     }
1923 
1924     /**
1925      * {@inheritDoc}
1926      *
1927      * @return the previous value associated with the specified key,
1928      *         or <tt>null</tt> if there was no mapping for the key
1929      * @throws ClassCastException if the specified key cannot be compared
1930      *         with the keys currently in the map
1931      * @throws NullPointerException if the specified key or value is null
1932      */
1933     public V replace(K key, V value) {
1934         if (value == null)
1935             throw new NullPointerException();
1936         Comparable<? super K> k = comparable(key);
1937         for (;;) {
1938             Node<K,V> n = findNode(k);
1939             if (n == null)
1940                 return null;
1941             Object v = n.value;
1942             if (v != null && n.casValue(v, value))
1943                 return (V)v;
1944         }
1945     }
1946 
1947     /* ------ SortedMap API methods ------ */
1948 
1949     public Comparator<? super K> comparator() {
1950         return comparator;
1951     }
1952 
1953     /**
1954      * @throws NoSuchElementException {@inheritDoc}
1955      */
1956     public K firstKey() {
1957         Node<K,V> n = findFirst();
1958         if (n == null)
1959             throw new NoSuchElementException();
1960         return n.key;
1961     }
1962 
1963     /**
1964      * @throws NoSuchElementException {@inheritDoc}
1965      */
1966     public K lastKey() {
1967         Node<K,V> n = findLast();
1968         if (n == null)
1969             throw new NoSuchElementException();
1970         return n.key;
1971     }
1972 
1973     /**
1974      * @throws ClassCastException {@inheritDoc}
1975      * @throws NullPointerException if {@code fromKey} or {@code toKey} is null
1976      * @throws IllegalArgumentException {@inheritDoc}
1977      */
1978     public ConcurrentNavigableMap<K,V> subMap(K fromKey,
1979                                               boolean fromInclusive,
1980                                               K toKey,
1981                                               boolean toInclusive) {
1982         if (fromKey == null || toKey == null)
1983             throw new NullPointerException();
1984         return new SubMap<K,V>
1985             (this, fromKey, fromInclusive, toKey, toInclusive, false);
1986     }
1987 
1988     /**
1989      * @throws ClassCastException {@inheritDoc}
1990      * @throws NullPointerException if {@code toKey} is null
1991      * @throws IllegalArgumentException {@inheritDoc}
1992      */
1993     public ConcurrentNavigableMap<K,V> headMap(K toKey,
1994                                                boolean inclusive) {
1995         if (toKey == null)
1996             throw new NullPointerException();
1997         return new SubMap<K,V>
1998             (this, null, false, toKey, inclusive, false);
1999     }
2000 
2001     /**
2002      * @throws ClassCastException {@inheritDoc}
2003      * @throws NullPointerException if {@code fromKey} is null
2004      * @throws IllegalArgumentException {@inheritDoc}
2005      */
2006     public ConcurrentNavigableMap<K,V> tailMap(K fromKey,
2007                                                boolean inclusive) {
2008         if (fromKey == null)
2009             throw new NullPointerException();
2010         return new SubMap<K,V>
2011             (this, fromKey, inclusive, null, false, false);
2012     }
2013 
2014     /**
2015      * @throws ClassCastException {@inheritDoc}
2016      * @throws NullPointerException if {@code fromKey} or {@code toKey} is null
2017      * @throws IllegalArgumentException {@inheritDoc}
2018      */
2019     public ConcurrentNavigableMap<K,V> subMap(K fromKey, K toKey) {
2020         return subMap(fromKey, true, toKey, false);
2021     }
2022 
2023     /**
2024      * @throws ClassCastException {@inheritDoc}
2025      * @throws NullPointerException if {@code toKey} is null
2026      * @throws IllegalArgumentException {@inheritDoc}
2027      */
2028     public ConcurrentNavigableMap<K,V> headMap(K toKey) {
2029         return headMap(toKey, false);
2030     }
2031 
2032     /**
2033      * @throws ClassCastException {@inheritDoc}
2034      * @throws NullPointerException if {@code fromKey} is null
2035      * @throws IllegalArgumentException {@inheritDoc}
2036      */
2037     public ConcurrentNavigableMap<K,V> tailMap(K fromKey) {
2038         return tailMap(fromKey, true);
2039     }
2040 
2041     /* ---------------- Relational operations -------------- */
2042 
2043     /**
2044      * Returns a key-value mapping associated with the greatest key
2045      * strictly less than the given key, or <tt>null</tt> if there is
2046      * no such key. The returned entry does <em>not</em> support the
2047      * <tt>Entry.setValue</tt> method.
2048      *
2049      * @throws ClassCastException {@inheritDoc}
2050      * @throws NullPointerException if the specified key is null
2051      */
2052     public Map.Entry<K,V> lowerEntry(K key) {
2053         return getNear(key, LT);
2054     }
2055 
2056     /**
2057      * @throws ClassCastException {@inheritDoc}
2058      * @throws NullPointerException if the specified key is null
2059      */
2060     public K lowerKey(K key) {
2061         Node<K,V> n = findNear(key, LT);
2062         return (n == null) ? null : n.key;
2063     }
2064 
2065     /**
2066      * Returns a key-value mapping associated with the greatest key
2067      * less than or equal to the given key, or <tt>null</tt> if there
2068      * is no such key. The returned entry does <em>not</em> support
2069      * the <tt>Entry.setValue</tt> method.
2070      *
2071      * @param key the key
2072      * @throws ClassCastException {@inheritDoc}
2073      * @throws NullPointerException if the specified key is null
2074      */
2075     public Map.Entry<K,V> floorEntry(K key) {
2076         return getNear(key, LT|EQ);
2077     }
2078 
2079     /**
2080      * @param key the key
2081      * @throws ClassCastException {@inheritDoc}
2082      * @throws NullPointerException if the specified key is null
2083      */
2084     public K floorKey(K key) {
2085         Node<K,V> n = findNear(key, LT|EQ);
2086         return (n == null) ? null : n.key;
2087     }
2088 
2089     /**
2090      * Returns a key-value mapping associated with the least key
2091      * greater than or equal to the given key, or <tt>null</tt> if
2092      * there is no such entry. The returned entry does <em>not</em>
2093      * support the <tt>Entry.setValue</tt> method.
2094      *
2095      * @throws ClassCastException {@inheritDoc}
2096      * @throws NullPointerException if the specified key is null
2097      */
2098     public Map.Entry<K,V> ceilingEntry(K key) {
2099         return getNear(key, GT|EQ);
2100     }
2101 
2102     /**
2103      * @throws ClassCastException {@inheritDoc}
2104      * @throws NullPointerException if the specified key is null
2105      */
2106     public K ceilingKey(K key) {
2107         Node<K,V> n = findNear(key, GT|EQ);
2108         return (n == null) ? null : n.key;
2109     }
2110 
2111     /**
2112      * Returns a key-value mapping associated with the least key
2113      * strictly greater than the given key, or <tt>null</tt> if there
2114      * is no such key. The returned entry does <em>not</em> support
2115      * the <tt>Entry.setValue</tt> method.
2116      *
2117      * @param key the key
2118      * @throws ClassCastException {@inheritDoc}
2119      * @throws NullPointerException if the specified key is null
2120      */
2121     public Map.Entry<K,V> higherEntry(K key) {
2122         return getNear(key, GT);
2123     }
2124 
2125     /**
2126      * @param key the key
2127      * @throws ClassCastException {@inheritDoc}
2128      * @throws NullPointerException if the specified key is null
2129      */
2130     public K higherKey(K key) {
2131         Node<K,V> n = findNear(key, GT);
2132         return (n == null) ? null : n.key;
2133     }
2134 
2135     /**
2136      * Returns a key-value mapping associated with the least
2137      * key in this map, or <tt>null</tt> if the map is empty.
2138      * The returned entry does <em>not</em> support
2139      * the <tt>Entry.setValue</tt> method.
2140      */
2141     public Map.Entry<K,V> firstEntry() {
2142         for (;;) {
2143             Node<K,V> n = findFirst();
2144             if (n == null)
2145                 return null;
2146             AbstractMap.SimpleImmutableEntry<K,V> e = n.createSnapshot();
2147             if (e != null)
2148                 return e;
2149         }
2150     }
2151 
2152     /**
2153      * Returns a key-value mapping associated with the greatest
2154      * key in this map, or <tt>null</tt> if the map is empty.
2155      * The returned entry does <em>not</em> support
2156      * the <tt>Entry.setValue</tt> method.
2157      */
2158     public Map.Entry<K,V> lastEntry() {
2159         for (;;) {
2160             Node<K,V> n = findLast();
2161             if (n == null)
2162                 return null;
2163             AbstractMap.SimpleImmutableEntry<K,V> e = n.createSnapshot();
2164             if (e != null)
2165                 return e;
2166         }
2167     }
2168 
2169     /**
2170      * Removes and returns a key-value mapping associated with
2171      * the least key in this map, or <tt>null</tt> if the map is empty.
2172      * The returned entry does <em>not</em> support
2173      * the <tt>Entry.setValue</tt> method.
2174      */
2175     public Map.Entry<K,V> pollFirstEntry() {
2176         return doRemoveFirstEntry();
2177     }
2178 
2179     /**
2180      * Removes and returns a key-value mapping associated with
2181      * the greatest key in this map, or <tt>null</tt> if the map is empty.
2182      * The returned entry does <em>not</em> support
2183      * the <tt>Entry.setValue</tt> method.
2184      */
2185     public Map.Entry<K,V> pollLastEntry() {
2186         return doRemoveLastEntry();
2187     }
2188 
2189 
2190     /* ---------------- Iterators -------------- */
2191 
2192     /**
2193      * Base of iterator classes:
2194      */
2195     abstract class Iter<T> implements Iterator<T> {
2196         /** the last node returned by next() */
2197         Node<K,V> lastReturned;
2198         /** the next node to return from next(); */
2199         Node<K,V> next;
2200         /** Cache of next value field to maintain weak consistency */
2201         V nextValue;
2202 
2203         /** Initializes ascending iterator for entire range. */
2204         Iter() {
2205             for (;;) {
2206                 next = findFirst();
2207                 if (next == null)
2208                     break;
2209                 Object x = next.value;
2210                 if (x != null && x != next) {
2211                     nextValue = (V) x;
2212                     break;
2213                 }
2214             }
2215         }
2216 
2217         public final boolean hasNext() {
2218             return next != null;
2219         }
2220 
2221         /** Advances next to higher entry. */
2222         final void advance() {
2223             if (next == null)
2224                 throw new NoSuchElementException();
2225             lastReturned = next;
2226             for (;;) {
2227                 next = next.next;
2228                 if (next == null)
2229                     break;
2230                 Object x = next.value;
2231                 if (x != null && x != next) {
2232                     nextValue = (V) x;
2233                     break;
2234                 }
2235             }
2236         }
2237 
2238         public void remove() {
2239             Node<K,V> l = lastReturned;
2240             if (l == null)
2241                 throw new IllegalStateException();
2242             // It would not be worth all of the overhead to directly
2243             // unlink from here. Using remove is fast enough.
2244             ConcurrentSkipListMap.this.remove(l.key);
2245             lastReturned = null;
2246         }
2247 
2248     }
2249 
2250     final class ValueIterator extends Iter<V> {
2251         public V next() {
2252             V v = nextValue;
2253             advance();
2254             return v;
2255         }
2256     }
2257 
2258     final class KeyIterator extends Iter<K> {
2259         public K next() {
2260             Node<K,V> n = next;
2261             advance();
2262             return n.key;
2263         }
2264     }
2265 
2266     final class EntryIterator extends Iter<Map.Entry<K,V>> {
2267         public Map.Entry<K,V> next() {
2268             Node<K,V> n = next;
2269             V v = nextValue;
2270             advance();
2271             return new AbstractMap.SimpleImmutableEntry<K,V>(n.key, v);
2272         }
2273     }
2274 
2275     // Factory methods for iterators needed by ConcurrentSkipListSet etc
2276 
2277     Iterator<K> keyIterator() {
2278         return new KeyIterator();
2279     }
2280 
2281     Iterator<V> valueIterator() {
2282         return new ValueIterator();
2283     }
2284 
2285     Iterator<Map.Entry<K,V>> entryIterator() {
2286         return new EntryIterator();
2287     }
2288 
2289     /* ---------------- View Classes -------------- */
2290 
2291     /*
2292      * View classes are static, delegating to a ConcurrentNavigableMap
2293      * to allow use by SubMaps, which outweighs the ugliness of
2294      * needing type-tests for Iterator methods.
2295      */
2296 
2297     static final <E> List<E> toList(Collection<E> c) {
2298         // Using size() here would be a pessimization.
2299         List<E> list = new ArrayList<E>();
2300         for (E e : c)
2301             list.add(e);
2302         return list;
2303     }
2304 
2305     static final class KeySet<E>
2306             extends AbstractSet<E> implements NavigableSet<E> {
2307         private final ConcurrentNavigableMap<E,Object> m;
2308         KeySet(ConcurrentNavigableMap<E,Object> map) { m = map; }
2309         public int size() { return m.size(); }
2310         public boolean isEmpty() { return m.isEmpty(); }
2311         public boolean contains(Object o) { return m.containsKey(o); }
2312         public boolean remove(Object o) { return m.remove(o) != null; }
2313         public void clear() { m.clear(); }
2314         public E lower(E e) { return m.lowerKey(e); }
2315         public E floor(E e) { return m.floorKey(e); }
2316         public E ceiling(E e) { return m.ceilingKey(e); }
2317         public E higher(E e) { return m.higherKey(e); }
2318         public Comparator<? super E> comparator() { return m.comparator(); }
2319         public E first() { return m.firstKey(); }
2320         public E last() { return m.lastKey(); }
2321         public E pollFirst() {
2322             Map.Entry<E,Object> e = m.pollFirstEntry();
2323             return (e == null) ? null : e.getKey();
2324         }
2325         public E pollLast() {
2326             Map.Entry<E,Object> e = m.pollLastEntry();
2327             return (e == null) ? null : e.getKey();
2328         }
2329         public Iterator<E> iterator() {
2330             if (m instanceof ConcurrentSkipListMap)
2331                 return ((ConcurrentSkipListMap<E,Object>)m).keyIterator();
2332             else
2333                 return ((ConcurrentSkipListMap.SubMap<E,Object>)m).keyIterator();
2334         }
2335         public boolean equals(Object o) {
2336             if (o == this)
2337                 return true;
2338             if (!(o instanceof Set))
2339                 return false;
2340             Collection<?> c = (Collection<?>) o;
2341             try {
2342                 return containsAll(c) && c.containsAll(this);
2343             } catch (ClassCastException unused)   {
2344                 return false;
2345             } catch (NullPointerException unused) {
2346                 return false;
2347             }
2348         }
2349         public Object[] toArray()     { return toList(this).toArray();  }
2350         public <T> T[] toArray(T[] a) { return toList(this).toArray(a); }
2351         public Iterator<E> descendingIterator() {
2352             return descendingSet().iterator();
2353         }
2354         public NavigableSet<E> subSet(E fromElement,
2355                                       boolean fromInclusive,
2356                                       E toElement,
2357                                       boolean toInclusive) {
2358             return new KeySet<E>(m.subMap(fromElement, fromInclusive,
2359                                           toElement,   toInclusive));
2360         }
2361         public NavigableSet<E> headSet(E toElement, boolean inclusive) {
2362             return new KeySet<E>(m.headMap(toElement, inclusive));
2363         }
2364         public NavigableSet<E> tailSet(E fromElement, boolean inclusive) {
2365             return new KeySet<E>(m.tailMap(fromElement, inclusive));
2366         }
2367         public NavigableSet<E> subSet(E fromElement, E toElement) {
2368             return subSet(fromElement, true, toElement, false);
2369         }
2370         public NavigableSet<E> headSet(E toElement) {
2371             return headSet(toElement, false);
2372         }
2373         public NavigableSet<E> tailSet(E fromElement) {
2374             return tailSet(fromElement, true);
2375         }
2376         public NavigableSet<E> descendingSet() {
2377             return new KeySet(m.descendingMap());
2378         }
2379     }
2380 
2381     static final class Values<E> extends AbstractCollection<E> {
2382         private final ConcurrentNavigableMap<Object, E> m;
2383         Values(ConcurrentNavigableMap<Object, E> map) {
2384             m = map;
2385         }
2386         public Iterator<E> iterator() {
2387             if (m instanceof ConcurrentSkipListMap)
2388                 return ((ConcurrentSkipListMap<Object,E>)m).valueIterator();
2389             else
2390                 return ((SubMap<Object,E>)m).valueIterator();
2391         }
2392         public boolean isEmpty() {
2393             return m.isEmpty();
2394         }
2395         public int size() {
2396             return m.size();
2397         }
2398         public boolean contains(Object o) {
2399             return m.containsValue(o);
2400         }
2401         public void clear() {
2402             m.clear();
2403         }
2404         public Object[] toArray()     { return toList(this).toArray();  }
2405         public <T> T[] toArray(T[] a) { return toList(this).toArray(a); }
2406     }
2407 
2408     static final class EntrySet<K1,V1> extends AbstractSet<Map.Entry<K1,V1>> {
2409         private final ConcurrentNavigableMap<K1, V1> m;
2410         EntrySet(ConcurrentNavigableMap<K1, V1> map) {
2411             m = map;
2412         }
2413 
2414         public Iterator<Map.Entry<K1,V1>> iterator() {
2415             if (m instanceof ConcurrentSkipListMap)
2416                 return ((ConcurrentSkipListMap<K1,V1>)m).entryIterator();
2417             else
2418                 return ((SubMap<K1,V1>)m).entryIterator();
2419         }
2420 
2421         public boolean contains(Object o) {
2422             if (!(o instanceof Map.Entry))
2423                 return false;
2424             Map.Entry<K1,V1> e = (Map.Entry<K1,V1>)o;
2425             V1 v = m.get(e.getKey());
2426             return v != null && v.equals(e.getValue());
2427         }
2428         public boolean remove(Object o) {
2429             if (!(o instanceof Map.Entry))
2430                 return false;
2431             Map.Entry<K1,V1> e = (Map.Entry<K1,V1>)o;
2432             return m.remove(e.getKey(),
2433                             e.getValue());
2434         }
2435         public boolean isEmpty() {
2436             return m.isEmpty();
2437         }
2438         public int size() {
2439             return m.size();
2440         }
2441         public void clear() {
2442             m.clear();
2443         }
2444         public boolean equals(Object o) {
2445             if (o == this)
2446                 return true;
2447             if (!(o instanceof Set))
2448                 return false;
2449             Collection<?> c = (Collection<?>) o;
2450             try {
2451                 return containsAll(c) && c.containsAll(this);
2452             } catch (ClassCastException unused)   {
2453                 return false;
2454             } catch (NullPointerException unused) {
2455                 return false;
2456             }
2457         }
2458         public Object[] toArray()     { return toList(this).toArray();  }
2459         public <T> T[] toArray(T[] a) { return toList(this).toArray(a); }
2460     }
2461 
2462     /**
2463      * Submaps returned by {@link ConcurrentSkipListMap} submap operations
2464      * represent a subrange of mappings of their underlying
2465      * maps. Instances of this class support all methods of their
2466      * underlying maps, differing in that mappings outside their range are
2467      * ignored, and attempts to add mappings outside their ranges result
2468      * in {@link IllegalArgumentException}.  Instances of this class are
2469      * constructed only using the <tt>subMap</tt>, <tt>headMap</tt>, and
2470      * <tt>tailMap</tt> methods of their underlying maps.
2471      *
2472      * @serial include
2473      */
2474     static final class SubMap<K,V> extends AbstractMap<K,V>
2475         implements ConcurrentNavigableMap<K,V>, Cloneable,
2476                    java.io.Serializable {
2477         private static final long serialVersionUID = -7647078645895051609L;
2478 
2479         /** Underlying map */
2480         private final ConcurrentSkipListMap<K,V> m;
2481         /** lower bound key, or null if from start */
2482         private final K lo;
2483         /** upper bound key, or null if to end */
2484         private final K hi;
2485         /** inclusion flag for lo */
2486         private final boolean loInclusive;
2487         /** inclusion flag for hi */
2488         private final boolean hiInclusive;
2489         /** direction */
2490         private final boolean isDescending;
2491 
2492         // Lazily initialized view holders
2493         private transient KeySet<K> keySetView;
2494         private transient Set<Map.Entry<K,V>> entrySetView;
2495         private transient Collection<V> valuesView;
2496 
2497         /**
2498          * Creates a new submap, initializing all fields
2499          */
2500         SubMap(ConcurrentSkipListMap<K,V> map,
2501                K fromKey, boolean fromInclusive,
2502                K toKey, boolean toInclusive,
2503                boolean isDescending) {
2504             if (fromKey != null && toKey != null &&
2505                 map.compare(fromKey, toKey) > 0)
2506                 throw new IllegalArgumentException("inconsistent range");
2507             this.m = map;
2508             this.lo = fromKey;
2509             this.hi = toKey;
2510             this.loInclusive = fromInclusive;
2511             this.hiInclusive = toInclusive;
2512             this.isDescending = isDescending;
2513         }
2514 
2515         /* ----------------  Utilities -------------- */
2516 
2517         private boolean tooLow(K key) {
2518             if (lo != null) {
2519                 int c = m.compare(key, lo);
2520                 if (c < 0 || (c == 0 && !loInclusive))
2521                     return true;
2522             }
2523             return false;
2524         }
2525 
2526         private boolean tooHigh(K key) {
2527             if (hi != null) {
2528                 int c = m.compare(key, hi);
2529                 if (c > 0 || (c == 0 && !hiInclusive))
2530                     return true;
2531             }
2532             return false;
2533         }
2534 
2535         private boolean inBounds(K key) {
2536             return !tooLow(key) && !tooHigh(key);
2537         }
2538 
2539         private void checkKeyBounds(K key) throws IllegalArgumentException {
2540             if (key == null)
2541                 throw new NullPointerException();
2542             if (!inBounds(key))
2543                 throw new IllegalArgumentException("key out of range");
2544         }
2545 
2546         /**
2547          * Returns true if node key is less than upper bound of range
2548          */
2549         private boolean isBeforeEnd(ConcurrentSkipListMap.Node<K,V> n) {
2550             if (n == null)
2551                 return false;
2552             if (hi == null)
2553                 return true;
2554             K k = n.key;
2555             if (k == null) // pass by markers and headers
2556                 return true;
2557             int c = m.compare(k, hi);
2558             if (c > 0 || (c == 0 && !hiInclusive))
2559                 return false;
2560             return true;
2561         }
2562 
2563         /**
2564          * Returns lowest node. This node might not be in range, so
2565          * most usages need to check bounds
2566          */
2567         private ConcurrentSkipListMap.Node<K,V> loNode() {
2568             if (lo == null)
2569                 return m.findFirst();
2570             else if (loInclusive)
2571                 return m.findNear(lo, m.GT|m.EQ);
2572             else
2573                 return m.findNear(lo, m.GT);
2574         }
2575 
2576         /**
2577          * Returns highest node. This node might not be in range, so
2578          * most usages need to check bounds
2579          */
2580         private ConcurrentSkipListMap.Node<K,V> hiNode() {
2581             if (hi == null)
2582                 return m.findLast();
2583             else if (hiInclusive)
2584                 return m.findNear(hi, m.LT|m.EQ);
2585             else
2586                 return m.findNear(hi, m.LT);
2587         }
2588 
2589         /**
2590          * Returns lowest absolute key (ignoring directonality)
2591          */
2592         private K lowestKey() {
2593             ConcurrentSkipListMap.Node<K,V> n = loNode();
2594             if (isBeforeEnd(n))
2595                 return n.key;
2596             else
2597                 throw new NoSuchElementException();
2598         }
2599 
2600         /**
2601          * Returns highest absolute key (ignoring directonality)
2602          */
2603         private K highestKey() {
2604             ConcurrentSkipListMap.Node<K,V> n = hiNode();
2605             if (n != null) {
2606                 K last = n.key;
2607                 if (inBounds(last))
2608                     return last;
2609             }
2610             throw new NoSuchElementException();
2611         }
2612 
2613         private Map.Entry<K,V> lowestEntry() {
2614             for (;;) {
2615                 ConcurrentSkipListMap.Node<K,V> n = loNode();
2616                 if (!isBeforeEnd(n))
2617                     return null;
2618                 Map.Entry<K,V> e = n.createSnapshot();
2619                 if (e != null)
2620                     return e;
2621             }
2622         }
2623 
2624         private Map.Entry<K,V> highestEntry() {
2625             for (;;) {
2626                 ConcurrentSkipListMap.Node<K,V> n = hiNode();
2627                 if (n == null || !inBounds(n.key))
2628                     return null;
2629                 Map.Entry<K,V> e = n.createSnapshot();
2630                 if (e != null)
2631                     return e;
2632             }
2633         }
2634 
2635         private Map.Entry<K,V> removeLowest() {
2636             for (;;) {
2637                 Node<K,V> n = loNode();
2638                 if (n == null)
2639                     return null;
2640                 K k = n.key;
2641                 if (!inBounds(k))
2642                     return null;
2643                 V v = m.doRemove(k, null);
2644                 if (v != null)
2645                     return new AbstractMap.SimpleImmutableEntry<K,V>(k, v);
2646             }
2647         }
2648 
2649         private Map.Entry<K,V> removeHighest() {
2650             for (;;) {
2651                 Node<K,V> n = hiNode();
2652                 if (n == null)
2653                     return null;
2654                 K k = n.key;
2655                 if (!inBounds(k))
2656                     return null;
2657                 V v = m.doRemove(k, null);
2658                 if (v != null)
2659                     return new AbstractMap.SimpleImmutableEntry<K,V>(k, v);
2660             }
2661         }
2662 
2663         /**
2664          * Submap version of ConcurrentSkipListMap.getNearEntry
2665          */
2666         private Map.Entry<K,V> getNearEntry(K key, int rel) {
2667             if (isDescending) { // adjust relation for direction
2668                 if ((rel & m.LT) == 0)
2669                     rel |= m.LT;
2670                 else
2671                     rel &= ~m.LT;
2672             }
2673             if (tooLow(key))
2674                 return ((rel & m.LT) != 0) ? null : lowestEntry();
2675             if (tooHigh(key))
2676                 return ((rel & m.LT) != 0) ? highestEntry() : null;
2677             for (;;) {
2678                 Node<K,V> n = m.findNear(key, rel);
2679                 if (n == null || !inBounds(n.key))
2680                     return null;
2681                 K k = n.key;
2682                 V v = n.getValidValue();
2683                 if (v != null)
2684                     return new AbstractMap.SimpleImmutableEntry<K,V>(k, v);
2685             }
2686         }
2687 
2688         // Almost the same as getNearEntry, except for keys
2689         private K getNearKey(K key, int rel) {
2690             if (isDescending) { // adjust relation for direction
2691                 if ((rel & m.LT) == 0)
2692                     rel |= m.LT;
2693                 else
2694                     rel &= ~m.LT;
2695             }
2696             if (tooLow(key)) {
2697                 if ((rel & m.LT) == 0) {
2698                     ConcurrentSkipListMap.Node<K,V> n = loNode();
2699                     if (isBeforeEnd(n))
2700                         return n.key;
2701                 }
2702                 return null;
2703             }
2704             if (tooHigh(key)) {
2705                 if ((rel & m.LT) != 0) {
2706                     ConcurrentSkipListMap.Node<K,V> n = hiNode();
2707                     if (n != null) {
2708                         K last = n.key;
2709                         if (inBounds(last))
2710                             return last;
2711                     }
2712                 }
2713                 return null;
2714             }
2715             for (;;) {
2716                 Node<K,V> n = m.findNear(key, rel);
2717                 if (n == null || !inBounds(n.key))
2718                     return null;
2719                 K k = n.key;
2720                 V v = n.getValidValue();
2721                 if (v != null)
2722                     return k;
2723             }
2724         }
2725 
2726         /* ----------------  Map API methods -------------- */
2727 
2728         public boolean containsKey(Object key) {
2729             if (key == null) throw new NullPointerException();
2730             K k = (K)key;
2731             return inBounds(k) && m.containsKey(k);
2732         }
2733 
2734         public V get(Object key) {
2735             if (key == null) throw new NullPointerException();
2736             K k = (K)key;
2737             return ((!inBounds(k)) ? null : m.get(k));
2738         }
2739 
2740         public V put(K key, V value) {
2741             checkKeyBounds(key);
2742             return m.put(key, value);
2743         }
2744 
2745         public V remove(Object key) {
2746             K k = (K)key;
2747             return (!inBounds(k)) ? null : m.remove(k);
2748         }
2749 
2750         public int size() {
2751             long count = 0;
2752             for (ConcurrentSkipListMap.Node<K,V> n = loNode();
2753                  isBeforeEnd(n);
2754                  n = n.next) {
2755                 if (n.getValidValue() != null)
2756                     ++count;
2757             }
2758             return count >= Integer.MAX_VALUE ? Integer.MAX_VALUE : (int)count;
2759         }
2760 
2761         public boolean isEmpty() {
2762             return !isBeforeEnd(loNode());
2763         }
2764 
2765         public boolean containsValue(Object value) {
2766             if (value == null)
2767                 throw new NullPointerException();
2768             for (ConcurrentSkipListMap.Node<K,V> n = loNode();
2769                  isBeforeEnd(n);
2770                  n = n.next) {
2771                 V v = n.getValidValue();
2772                 if (v != null && value.equals(v))
2773                     return true;
2774             }
2775             return false;
2776         }
2777 
2778         public void clear() {
2779             for (ConcurrentSkipListMap.Node<K,V> n = loNode();
2780                  isBeforeEnd(n);
2781                  n = n.next) {
2782                 if (n.getValidValue() != null)
2783                     m.remove(n.key);
2784             }
2785         }
2786 
2787         /* ----------------  ConcurrentMap API methods -------------- */
2788 
2789         public V putIfAbsent(K key, V value) {
2790             checkKeyBounds(key);
2791             return m.putIfAbsent(key, value);
2792         }
2793 
2794         public boolean remove(Object key, Object value) {
2795             K k = (K)key;
2796             return inBounds(k) && m.remove(k, value);
2797         }
2798 
2799         public boolean replace(K key, V oldValue, V newValue) {
2800             checkKeyBounds(key);
2801             return m.replace(key, oldValue, newValue);
2802         }
2803 
2804         public V replace(K key, V value) {
2805             checkKeyBounds(key);
2806             return m.replace(key, value);
2807         }
2808 
2809         /* ----------------  SortedMap API methods -------------- */
2810 
2811         public Comparator<? super K> comparator() {
2812             Comparator<? super K> cmp = m.comparator();
2813             if (isDescending)
2814                 return Collections.reverseOrder(cmp);
2815             else
2816                 return cmp;
2817         }
2818 
2819         /**
2820          * Utility to create submaps, where given bounds override
2821          * unbounded(null) ones and/or are checked against bounded ones.
2822          */
2823         private SubMap<K,V> newSubMap(K fromKey,
2824                                       boolean fromInclusive,
2825                                       K toKey,
2826                                       boolean toInclusive) {
2827             if (isDescending) { // flip senses
2828                 K tk = fromKey;
2829                 fromKey = toKey;
2830                 toKey = tk;
2831                 boolean ti = fromInclusive;
2832                 fromInclusive = toInclusive;
2833                 toInclusive = ti;
2834             }
2835             if (lo != null) {
2836                 if (fromKey == null) {
2837                     fromKey = lo;
2838                     fromInclusive = loInclusive;
2839                 }
2840                 else {
2841                     int c = m.compare(fromKey, lo);
2842                     if (c < 0 || (c == 0 && !loInclusive && fromInclusive))
2843                         throw new IllegalArgumentException("key out of range");
2844                 }
2845             }
2846             if (hi != null) {
2847                 if (toKey == null) {
2848                     toKey = hi;
2849                     toInclusive = hiInclusive;
2850                 }
2851                 else {
2852                     int c = m.compare(toKey, hi);
2853                     if (c > 0 || (c == 0 && !hiInclusive && toInclusive))
2854                         throw new IllegalArgumentException("key out of range");
2855                 }
2856             }
2857             return new SubMap<K,V>(m, fromKey, fromInclusive,
2858                                    toKey, toInclusive, isDescending);
2859         }
2860 
2861         public SubMap<K,V> subMap(K fromKey,
2862                                   boolean fromInclusive,
2863                                   K toKey,
2864                                   boolean toInclusive) {
2865             if (fromKey == null || toKey == null)
2866                 throw new NullPointerException();
2867             return newSubMap(fromKey, fromInclusive, toKey, toInclusive);
2868         }
2869 
2870         public SubMap<K,V> headMap(K toKey,
2871                                    boolean inclusive) {
2872             if (toKey == null)
2873                 throw new NullPointerException();
2874             return newSubMap(null, false, toKey, inclusive);
2875         }
2876 
2877         public SubMap<K,V> tailMap(K fromKey,
2878                                    boolean inclusive) {
2879             if (fromKey == null)
2880                 throw new NullPointerException();
2881             return newSubMap(fromKey, inclusive, null, false);
2882         }
2883 
2884         public SubMap<K,V> subMap(K fromKey, K toKey) {
2885             return subMap(fromKey, true, toKey, false);
2886         }
2887 
2888         public SubMap<K,V> headMap(K toKey) {
2889             return headMap(toKey, false);
2890         }
2891 
2892         public SubMap<K,V> tailMap(K fromKey) {
2893             return tailMap(fromKey, true);
2894         }
2895 
2896         public SubMap<K,V> descendingMap() {
2897             return new SubMap<K,V>(m, lo, loInclusive,
2898                                    hi, hiInclusive, !isDescending);
2899         }
2900 
2901         /* ----------------  Relational methods -------------- */
2902 
2903         public Map.Entry<K,V> ceilingEntry(K key) {
2904             return getNearEntry(key, (m.GT|m.EQ));
2905         }
2906 
2907         public K ceilingKey(K key) {
2908             return getNearKey(key, (m.GT|m.EQ));
2909         }
2910 
2911         public Map.Entry<K,V> lowerEntry(K key) {
2912             return getNearEntry(key, (m.LT));
2913         }
2914 
2915         public K lowerKey(K key) {
2916             return getNearKey(key, (m.LT));
2917         }
2918 
2919         public Map.Entry<K,V> floorEntry(K key) {
2920             return getNearEntry(key, (m.LT|m.EQ));
2921         }
2922 
2923         public K floorKey(K key) {
2924             return getNearKey(key, (m.LT|m.EQ));
2925         }
2926 
2927         public Map.Entry<K,V> higherEntry(K key) {
2928             return getNearEntry(key, (m.GT));
2929         }
2930 
2931         public K higherKey(K key) {
2932             return getNearKey(key, (m.GT));
2933         }
2934 
2935         public K firstKey() {
2936             return isDescending ? highestKey() : lowestKey();
2937         }
2938 
2939         public K lastKey() {
2940             return isDescending ? lowestKey() : highestKey();
2941         }
2942 
2943         public Map.Entry<K,V> firstEntry() {
2944             return isDescending ? highestEntry() : lowestEntry();
2945         }
2946 
2947         public Map.Entry<K,V> lastEntry() {
2948             return isDescending ? lowestEntry() : highestEntry();
2949         }
2950 
2951         public Map.Entry<K,V> pollFirstEntry() {
2952             return isDescending ? removeHighest() : removeLowest();
2953         }
2954 
2955         public Map.Entry<K,V> pollLastEntry() {
2956             return isDescending ? removeLowest() : removeHighest();
2957         }
2958 
2959         /* ---------------- Submap Views -------------- */
2960 
2961         public NavigableSet<K> keySet() {
2962             KeySet<K> ks = keySetView;
2963             return (ks != null) ? ks : (keySetView = new KeySet(this));
2964         }
2965 
2966         public NavigableSet<K> navigableKeySet() {
2967             KeySet<K> ks = keySetView;
2968             return (ks != null) ? ks : (keySetView = new KeySet(this));
2969         }
2970 
2971         public Collection<V> values() {
2972             Collection<V> vs = valuesView;
2973             return (vs != null) ? vs : (valuesView = new Values(this));
2974         }
2975 
2976         public Set<Map.Entry<K,V>> entrySet() {
2977             Set<Map.Entry<K,V>> es = entrySetView;
2978             return (es != null) ? es : (entrySetView = new EntrySet(this));
2979         }
2980 
2981         public NavigableSet<K> descendingKeySet() {
2982             return descendingMap().navigableKeySet();
2983         }
2984 
2985         Iterator<K> keyIterator() {
2986             return new SubMapKeyIterator();
2987         }
2988 
2989         Iterator<V> valueIterator() {
2990             return new SubMapValueIterator();
2991         }
2992 
2993         Iterator<Map.Entry<K,V>> entryIterator() {
2994             return new SubMapEntryIterator();
2995         }
2996 
2997         /**
2998          * Variant of main Iter class to traverse through submaps.
2999          */
3000         abstract class SubMapIter<T> implements Iterator<T> {
3001             /** the last node returned by next() */
3002             Node<K,V> lastReturned;
3003             /** the next node to return from next(); */
3004             Node<K,V> next;
3005             /** Cache of next value field to maintain weak consistency */
3006             V nextValue;
3007 
3008             SubMapIter() {
3009                 for (;;) {
3010                     next = isDescending ? hiNode() : loNode();
3011                     if (next == null)
3012                         break;
3013                     Object x = next.value;
3014                     if (x != null && x != next) {
3015                         if (! inBounds(next.key))
3016                             next = null;
3017                         else
3018                             nextValue = (V) x;
3019                         break;
3020                     }
3021                 }
3022             }
3023 
3024             public final boolean hasNext() {
3025                 return next != null;
3026             }
3027 
3028             final void advance() {
3029                 if (next == null)
3030                     throw new NoSuchElementException();
3031                 lastReturned = next;
3032                 if (isDescending)
3033                     descend();
3034                 else
3035                     ascend();
3036             }
3037 
3038             private void ascend() {
3039                 for (;;) {
3040                     next = next.next;
3041                     if (next == null)
3042                         break;
3043                     Object x = next.value;
3044                     if (x != null && x != next) {
3045                         if (tooHigh(next.key))
3046                             next = null;
3047                         else
3048                             nextValue = (V) x;
3049                         break;
3050                     }
3051                 }
3052             }
3053 
3054             private void descend() {
3055                 for (;;) {
3056                     next = m.findNear(lastReturned.key, LT);
3057                     if (next == null)
3058                         break;
3059                     Object x = next.value;
3060                     if (x != null && x != next) {
3061                         if (tooLow(next.key))
3062                             next = null;
3063                         else
3064                             nextValue = (V) x;
3065                         break;
3066                     }
3067                 }
3068             }
3069 
3070             public void remove() {
3071                 Node<K,V> l = lastReturned;
3072                 if (l == null)
3073                     throw new IllegalStateException();
3074                 m.remove(l.key);
3075                 lastReturned = null;
3076             }
3077 
3078         }
3079 
3080         final class SubMapValueIterator extends SubMapIter<V> {
3081             public V next() {
3082                 V v = nextValue;
3083                 advance();
3084                 return v;
3085             }
3086         }
3087 
3088         final class SubMapKeyIterator extends SubMapIter<K> {
3089             public K next() {
3090                 Node<K,V> n = next;
3091                 advance();
3092                 return n.key;
3093             }
3094         }
3095 
3096         final class SubMapEntryIterator extends SubMapIter<Map.Entry<K,V>> {
3097             public Map.Entry<K,V> next() {
3098                 Node<K,V> n = next;
3099                 V v = nextValue;
3100                 advance();
3101                 return new AbstractMap.SimpleImmutableEntry<K,V>(n.key, v);
3102             }
3103         }
3104     }
3105 
3106     // Unsafe mechanics
3107     private static final sun.misc.Unsafe UNSAFE;
3108     private static final long headOffset;
3109     static {
3110         try {
3111             UNSAFE = sun.misc.Unsafe.getUnsafe();
3112             Class k = ConcurrentSkipListMap.class;
3113             headOffset = UNSAFE.objectFieldOffset
3114                 (k.getDeclaredField("head"));
3115         } catch (Exception e) {
3116             throw new Error(e);
3117         }
3118     }
3119 }
View Code

 

下面从ConcurrentSkipListMap的添加,删除,获取这3个方面对它进行分析。

1. 添加

下面以put(K key, V value)为例,对ConcurrentSkipListMap的添加方法进行说明。

public V put(K key, V value) {
    if (value == null)
        throw new NullPointerException();
    return doPut(key, value, false);
}

实际上,put()是通过doPut()将key-value键值对添加到ConcurrentSkipListMap中的。

doPut()的源码如下:

Java多线程系列--“JUC集合”05之 ConcurrentSkipListMap
private V doPut(K kkey, V value, boolean onlyIfAbsent) {
    Comparable<? super K> key = comparable(kkey);
    for (;;) {
        // 找到key的前继节点
        Node<K,V> b = findPredecessor(key);
        // 设置n为“key的前继节点的后继节点”,即n应该是“插入节点”的“后继节点”
        Node<K,V> n = b.next;
        for (;;) {
            if (n != null) {
                Node<K,V> f = n.next;
                // 如果两次获得的b.next不是相同的Node,就跳转到”外层for循环“,重新获得b和n后再遍历。
                if (n != b.next)
                    break;
                // v是“n的值”
                Object v = n.value;
                // 当n的值为null(意味着其它线程删除了n);此时删除b的下一个节点,然后跳转到”外层for循环“,重新获得b和n后再遍历。
                if (v == null) {               // n is deleted
                    n.helpDelete(b, f);
                    break;
                }
                // 如果其它线程删除了b;则跳转到”外层for循环“,重新获得b和n后再遍历。
                if (v == n || b.value == null) // b is deleted
                    break;
                // 比较key和n.key
                int c = key.compareTo(n.key);
                if (c > 0) {
                    b = n;
                    n = f;
                    continue;
                }
                if (c == 0) {
                    if (onlyIfAbsent || n.casValue(v, value))
                        return (V)v;
                    else
                        break; // restart if lost race to replace value
                }
                // else c < 0; fall through
            }

            // 新建节点(对应是“要插入的键值对”)
            Node<K,V> z = new Node<K,V>(kkey, value, n);
            // 设置“b的后继节点”为z
            if (!b.casNext(n, z))
                break;         // 多线程情况下,break才可能发生(其它线程对b进行了操作)
            // 随机获取一个level
            // 然后在“第1层”到“第level层”的链表中都插入新建节点
            int level = randomLevel();
            if (level > 0)
                insertIndex(z, level);
            return null;
        }
    }
}
Java多线程系列--“JUC集合”05之 ConcurrentSkipListMap

说明:doPut() 的作用就是将键值对添加到“跳表”中。
要想搞清doPut(),首先要弄清楚它的主*分 —— 我们先单纯的只考虑“单线程的情况下,将key-value添加到跳表中”,即忽略“多线程相关的内容”。它的流程如下:
第1步:找到“插入位置”。
即,找到“key的前继节点(b)”和“key的后继节点(n)”;key是要插入节点的键。
第2步:新建并插入节点。
即,新建节点z(key对应的节点),并将新节点z插入到“跳表”中(设置“b的后继节点为z”,“z的后继节点为n”)。
第3步:更新跳表。
即,随机获取一个level,然后在“跳表”的第1层~第level层之间,每一层都插入节点z;在第level层之上就不再插入节点了。若level数值大于“跳表的层次”,则新建一层。
主*分“对应的精简后的doPut()的代码”如下(仅供参考):

Java多线程系列--“JUC集合”05之 ConcurrentSkipListMap
private V doPut(K kkey, V value, boolean onlyIfAbsent) {
    Comparable<? super K> key = comparable(kkey);
    for (;;) {
        // 找到key的前继节点
        Node<K,V> b = findPredecessor(key);
        // 设置n为key的后继节点
        Node<K,V> n = b.next;
        for (;;) {
            
            // 新建节点(对应是“要被插入的键值对”)
            Node<K,V> z = new Node<K,V>(kkey, value, n);
            // 设置“b的后继节点”为z
            b.casNext(n, z);

            // 随机获取一个level
            // 然后在“第1层”到“第level层”的链表中都插入新建节点
            int level = randomLevel();
            if (level > 0)
                insertIndex(z, level);
            return null;
        }
    }
}
Java多线程系列--“JUC集合”05之 ConcurrentSkipListMap

理清主干之后,剩余的工作就相对简单了。主要是上面几步的对应算法的具体实现,以及多线程相关情况的处理!

 

2. 删除

下面以remove(Object key)为例,对ConcurrentSkipListMap的删除方法进行说明。

public V remove(Object key) {
    return doRemove(key, null);
}

实际上,remove()是通过doRemove()将ConcurrentSkipListMap中的key对应的键值对删除的。

doRemove()的源码如下:

 

Java多线程系列--“JUC集合”05之 ConcurrentSkipListMap
final V doRemove(Object okey, Object value) {
    Comparable<? super K> key = comparable(okey);
    for (;;) {
        // 找到“key的前继节点”
        Node<K,V> b = findPredecessor(key);
        // 设置n为“b的后继节点”(即若key存在于“跳表中”,n就是key对应的节点)
        Node<K,V> n = b.next;
        for (;;) {
            if (n == null)
                return null;
            // f是“当前节点n的后继节点”
            Node<K,V> f = n.next;
            // 如果两次读取到的“b的后继节点”不同(其它线程操作了该跳表),则返回到“外层for循环”重新遍历。
            if (n != b.next)                    // inconsistent read
                break;
            // 如果“当前节点n的值”变为null(其它线程操作了该跳表),则返回到“外层for循环”重新遍历。
            Object v = n.value;
            if (v == null) {                    // n is deleted
                n.helpDelete(b, f);
                break;
            }
            // 如果“前继节点b”被删除(其它线程操作了该跳表),则返回到“外层for循环”重新遍历。
            if (v == n || b.value == null)      // b is deleted
                break;
            int c = key.compareTo(n.key);
            if (c < 0)
                return null;
            if (c > 0) {
                b = n;
                n = f;
                continue;
            }

            // 以下是c=0的情况
            if (value != null && !value.equals(v))
                return null;
            // 设置“当前节点n”的值为null
            if (!n.casValue(v, null))
                break;
            // 设置“b的后继节点”为f
            if (!n.appendMarker(f) || !b.casNext(n, f))
                findNode(key);                  // Retry via findNode
            else {
                // 清除“跳表”中每一层的key节点
                findPredecessor(key);           // Clean index
                // 如果“表头的右索引为空”,则将“跳表的层次”-1。
                if (head.right == null)
                    tryReduceLevel();
            }
            return (V)v;
        }
    }
}
Java多线程系列--“JUC集合”05之 ConcurrentSkipListMap

说明:doRemove()的作用是删除跳表中的节点。
和doPut()一样,我们重点看doRemove()的主*分,了解主*分之后,其余部分就非常容易理解了。下面是“单线程的情况下,删除跳表中键值对的步骤”:
第1步:找到“被删除节点的位置”。
即,找到“key的前继节点(b)”,“key所对应的节点(n)”,“n的后继节点f”;key是要删除节点的键。
第2步:删除节点。
即,将“key所对应的节点n”从跳表中移除 -- 将“b的后继节点”设为“f”!
第3步:更新跳表。
即,遍历跳表,删除每一层的“key节点”(如果存在的话)。如果删除“key节点”之后,跳表的层次需要-1;则执行相应的操作!
主*分“对应的精简后的doRemove()的代码”如下(仅供参考):

 

Java多线程系列--“JUC集合”05之 ConcurrentSkipListMap
final V doRemove(Object okey, Object value) {
    Comparable<? super K> key = comparable(okey);
    for (;;) {
        // 找到“key的前继节点”
        Node<K,V> b = findPredecessor(key);
        // 设置n为“b的后继节点”(即若key存在于“跳表中”,n就是key对应的节点)
        Node<K,V> n = b.next;
        for (;;) {
            // f是“当前节点n的后继节点”
            Node<K,V> f = n.next;

            // 设置“当前节点n”的值为null
            n.casValue(v, null);

            // 设置“b的后继节点”为f
            b.casNext(n, f);
            // 清除“跳表”中每一层的key节点
            findPredecessor(key);
            // 如果“表头的右索引为空”,则将“跳表的层次”-1。
            if (head.right == null)
                tryReduceLevel();
            return (V)v;
        }
    }
}
Java多线程系列--“JUC集合”05之 ConcurrentSkipListMap

 

3. 获取

下面以get(Object key)为例,对ConcurrentSkipListMap的获取方法进行说明。

public V get(Object key) {
    return doGet(key);
}

doGet的源码如下:

Java多线程系列--“JUC集合”05之 ConcurrentSkipListMap
private V doGet(Object okey) {
    Comparable<? super K> key = comparable(okey);
    for (;;) {
        // 找到“key对应的节点”
        Node<K,V> n = findNode(key);
        if (n == null)
            return null;
        Object v = n.value;
        if (v != null)
            return (V)v;
    }
}
Java多线程系列--“JUC集合”05之 ConcurrentSkipListMap

说明:doGet()是通过findNode()找到并返回节点的。

Java多线程系列--“JUC集合”05之 ConcurrentSkipListMap
private Node<K,V> findNode(Comparable<? super K> key) {
    for (;;) {
        // 找到key的前继节点
        Node<K,V> b = findPredecessor(key);
        // 设置n为“b的后继节点”(即若key存在于“跳表中”,n就是key对应的节点)
        Node<K,V> n = b.next;
        for (;;) {
            // 如果“n为null”,则跳转中不存在key对应的节点,直接返回null。
            if (n == null)
                return null;
            Node<K,V> f = n.next;
            // 如果两次读取到的“b的后继节点”不同(其它线程操作了该跳表),则返回到“外层for循环”重新遍历。
            if (n != b.next)                // inconsistent read
                break;
            Object v = n.value;
            // 如果“当前节点n的值”变为null(其它线程操作了该跳表),则返回到“外层for循环”重新遍历。
            if (v == null) {                // n is deleted
                n.helpDelete(b, f);
                break;
            }
            if (v == n || b.value == null)  // b is deleted
                break;
            // 若n是当前节点,则返回n。
            int c = key.compareTo(n.key);
            if (c == 0)
                return n;
            // 若“节点n的key”小于“key”,则说明跳表中不存在key对应的节点,返回null
            if (c < 0)
                return null;
            // 若“节点n的key”大于“key”,则更新b和n,继续查找。
            b = n;
            n = f;
        }
    }
}
Java多线程系列--“JUC集合”05之 ConcurrentSkipListMap

说明:findNode(key)的作用是在返回跳表中key对应的节点;存在则返回节点,不存在则返回null。
先弄清函数的主*分,即抛开“多线程相关内容”,单纯的考虑单线程情况下,从跳表获取节点的算法。
第1步:找到“被删除节点的位置”。
根据findPredecessor()定位key所在的层次以及找到key的前继节点(b),然后找到b的后继节点n。
第2步:根据“key的前继节点(b)”和“key的前继节点的后继节点(n)”来定位“key对应的节点”。
具体是通过比较“n的键值”和“key”的大小。如果相等,则n就是所要查找的键。

 

ConcurrentSkipListMap示例

Java多线程系列--“JUC集合”05之 ConcurrentSkipListMap
import java.util.*;
import java.util.concurrent.*;

/*
 *   ConcurrentSkipListMap是“线程安全”的哈希表,而TreeMap是非线程安全的。
 *
 *   下面是“多个线程同时操作并且遍历map”的示例
 *   (01) 当map是ConcurrentSkipListMap对象时,程序能正常运行。
 *   (02) 当map是TreeMap对象时,程序会产生ConcurrentModificationException异常。
 *
 * @author skywang
 */
public class ConcurrentSkipListMapDemo1 {

    // TODO: map是TreeMap对象时,程序会出错。
    //private static Map<String, String> map = new TreeMap<String, String>();
    private static Map<String, String> map = new ConcurrentSkipListMap<String, String>();
    public static void main(String[] args) {
    
        // 同时启动两个线程对map进行操作!
        new MyThread("a").start();
        new MyThread("b").start();
    }

    private static void printAll() {
        String key, value;
        Iterator iter = map.entrySet().iterator();
        while(iter.hasNext()) {
            Map.Entry entry = (Map.Entry)iter.next();
            key = (String)entry.getKey();
            value = (String)entry.getValue();
            System.out.print("("+key+", "+value+"), ");
        }
        System.out.println();
    }

    private static class MyThread extends Thread {
        MyThread(String name) {
            super(name);
        }
        @Override
        public void run() {
                int i = 0;
            while (i++ < 6) {
                // “线程名” + "序号"
                String val = Thread.currentThread().getName()+i;
                map.put(val, "0");
                // 通过“Iterator”遍历map。
                printAll();
            }
        }
    }
}
Java多线程系列--“JUC集合”05之 ConcurrentSkipListMap

(某一次)运行结果

 

Java多线程系列--“JUC集合”05之 ConcurrentSkipListMap
(a1, 0), (a1, 0), (b1, 0), (b1, 0),

(a1, 0), (b1, 0), (b2, 0), 
(a1, 0), (a1, 0), (a2, 0), (a2, 0), (b1, 0), (b1, 0), (b2, 0), (b2, 0), (b3, 0), 
(b3, 0), (a1, 0), 
(a2, 0), (a3, 0), (a1, 0), (b1, 0), (a2, 0), (b2, 0), (a3, 0), (b3, 0), (b1, 0), (b4, 0), 
(b2, 0), (a1, 0), (b3, 0), (a2, 0), (b4, 0), 
(a3, 0), (a1, 0), (a4, 0), (a2, 0), (b1, 0), (a3, 0), (b2, 0), (a4, 0), (b3, 0), (b1, 0), (b4, 0), (b2, 0), (b5, 0), 
(b3, 0), (a1, 0), (b4, 0), (a2, 0), (b5, 0), 
(a3, 0), (a1, 0), (a4, 0), (a2, 0), (a5, 0), (a3, 0), (b1, 0), (a4, 0), (b2, 0), (a5, 0), (b3, 0), (b1, 0), (b4, 0), (b2, 0), (b5, 0), (b3, 0), (b6, 0), 
(b4, 0), (a1, 0), (b5, 0), (a2, 0), (b6, 0), 
(a3, 0), (a4, 0), (a5, 0), (a6, 0), (b1, 0), (b2, 0), (b3, 0), (b4, 0), (b5, 0), (b6, 0), 
Java多线程系列--“JUC集合”05之 ConcurrentSkipListMap

结果说明
示例程序中,启动两个线程(线程a和线程b)分别对ConcurrentSkipListMap进行操作。以线程a而言,它会先获取“线程名”+“序号”,然后将该字符串作为key,将“0”作为value,插入到ConcurrentSkipListMap中;接着,遍历并输出ConcurrentSkipListMap中的全部元素。 线程b的操作和线程a一样,只不过线程b的名字和线程a的名字不同。
当map是ConcurrentSkipListMap对象时,程序能正常运行。如果将map改为TreeMap时,程序会产生ConcurrentModificationException异常。

 


更多内容

1. Java多线程系列--“JUC集合”01之 框架

2. Java多线程系列目录(共xx篇)

 

Java多线程系列--“JUC集合”05之 ConcurrentSkipListMap

上一篇:Kubernetes API Aggregated 是什么


下一篇:我不建议在C#中用下划线_开头来表示私有字段