jdk 源码分析(5)java ConcurrentSkipListMap结构

理解ConcurrentSkipListMap 只需要理解存储方式就行了

clip_image007

跳表结构之下往上分层,比如需要找117,首先会判断最高层,先比较21,在比较37 ,再比较37左边的,因为左边结束了,所以只能往下走,一直找到目标为止:

寻找规则,从最高层开始,先右,再下,直到最后。

1)单个节点定义:链式。
static final class Node<K,V> {
    final K key;
    volatile Object value;
    volatile Node<K,V> next;

    /**
     * Creates a new regular node.
     */
    Node(K key, Object value, Node<K,V> next) {
        this.key = key;
        this.value = value;
        this.next = next;
    }
2)单个节点,主要增加对right和down的指引
static class Index<K,V> {
    final Node<K,V> node;
    final Index<K,V> down;
    volatile Index<K,V> right;

    /**
     * Creates index node with given values.
     */
    Index(Node<K,V> node, Index<K,V> down, Index<K,V> right) {
        this.node = node;
        this.down = down;
        this.right = right;
    }
3)再次包装,产生对leve的定义。
static final class HeadIndex<K,V> extends Index<K,V> {
    final int level;
    HeadIndex(Node<K,V> node, Index<K,V> down, Index<K,V> right, int level) {
        super(node, down, right);
        this.level = level;
    }
}

如果对数据结构了解,上面headIndex 就可以构成跳表。

put的时候查找位置:
   
   
  1. private Node<K,V> findPredecessor(Object key, Comparator<? super K> cmp) {
  2. if (key == null)
  3. throw new NullPointerException(); // don't postpone errors
  4. for (;;) {//先找right
  5. for (Index<K,V> q = head, r = q.right, d;;) {
  6. if (r != null) {
  7. Node<K,V> n = r.node;
  8. K k = n.key;
  9. if (n.value == null) {
  10. if (!q.unlink(r))
  11. break; // restart
  12. r = q.right; // reread r
  13. continue;
  14. }
  15. if (cpr(cmp, key, k) > 0) {
  16. q = r;
  17. r = r.right;
  18. continue;
  19. }
  20. }
  21. //再找down
  22. if ((d = q.down) == null)
  23. return q.node;
  24. q = d;
  25. r = d.right;
  26. }
  27. }
可以看到都是先右边再下边。

不过这里的跳表有点不同,每个节点不是一个单点,而是一个链表。通过next 连接。
   
   
  1. for (Node<K,V> b = findPredecessor(key, cmp), n = b.next;;) {
  2. if (n != null) {
  3. Object v; int c;
  4. Node<K,V> f = n.next;
  5. if (n != b.next) // inconsistent read
  6. break;
  7. if ((v = n.value) == null) { // n is deleted
  8. n.helpDelete(b, f);
  9. break;
  10. }
  11. if (b.value == null || v == n) // b is deleted
  12. break;
  13. if ((c = cpr(cmp, key, n.key)) > 0) {
  14. b = n;
  15. n = f;
  16. continue;
  17. }
  18. if (c == 0) {
  19. if (onlyIfAbsent || n.casValue(v, value)) {
  20. @SuppressWarnings("unchecked") V vv = (V)v;
  21. return vv;
  22. }
  23. break; // restart if lost race to replace value
  24. }
  25. // else c < 0; fall through
  26. }
  27. z = new Node<K,V>(key, value, n);
  28. if (!b.casNext(n, z))
  29. break; // restart if lost race to append to b
  30. break outer;
  31. }
  32. }

里面还有 // find insertion points and splice in

数据的level配置,已经插入新的节点。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值