Git Product home page Git Product logo

Comments (1)

Snailclimb avatar Snailclimb commented on June 1, 2024

如果 get 方法要获取的节点是个链表或红黑树

线程 1 在执行扩容操作

final Node<K,V>[] resize() {
    
    ...

    // 线程1正在执行扩容操作,但还未执行到这,所以目前通过get方法获取元素,使用的还是旧数组,计算下标时用的还是旧数组的大小
    table = newTab;

    ...

    return newTab;
}

线程 2 执行 get 方法

final Node<K,V> getNode(int hash, Object key) {
    Node<K,V>[] tab; Node<K,V> first, e; int n; K k;
    // 线程2仍用旧数组的大小来获取下标位置
    if ((tab = table) != null && (n = tab.length) > 0 &&
        (first = tab[(n - 1) & hash]) != null) {
        ...
        // 假如发现该位置是个红黑树或链表,准备遍历红黑树或链表,这时已经不需要再使用数组了,所以线程1将当前的数组指向数组也没关系
        if ((e = first.next) != null) {
            if (first instanceof TreeNode)
                return ((TreeNode<K,V>)first).getTreeNode(hash, key);
            do {
                if (e.hash == hash &&
                    ((k = e.key) == key || (key != null && key.equals(k))))
                    return e;
            } while ((e = e.next) != null);
        }
    }
    return null;
}

线程 1 继续执行扩容操作

final Node<K,V>[] resize() {
    
    ...

    // 线程1继续往后执行
    table = newTab;
    if (oldTab != null) {
        // 将旧数组内的元素移到新数组中
        for (int j = 0; j < oldCap; ++j) {
            Node<K,V> e;
            if ((e = oldTab[j]) != null) {
                oldTab[j] = null;
                ...
                // 红黑树的分割操作
                else if (e instanceof TreeNode)
                ...
                // 链表的分割操作
                else {
                    ...
                }
            }
        }
    }
    return newTab;
}

如果线程 2 现在正在遍历红黑树或链表,这时线程 1 可能正在执行分割操作,也可能已经执行完分割操作。不管怎样,线程 2 当前遍历的红黑树或链表中,节点中维护的指针都可能产生了变化,如果很不巧的,线程 2 想查找的元素,正好在另一个红黑树或链表中,就会导致返回 null,虽然这个元素之前确实存在在该位置

感谢指出,如果感兴趣的话,可以在内容上提交一个PR完善一下,

from javaguide.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.