为什么hashmap是线程不安全的?

今天电话面试终端开发岗被问到了这题,怎奈何我菜的一笔,没答上来,特来学习一番,果然做了一年底软现在只会配寄存器了!!

言归正传,其实这题是想问你三点:1、hashmap插入的时候为什么是线程不安全的2、hashmap删除的时候为什么是线程不安全的3、hashmap resize的时候为什么是线程不安全的?

首先要明确什么是线程安全:也就是在多线程的情况下能不能保证资源的互斥。(这儿可能又会问synchronized与Lock的区别与使用)

对于插入来说put会调用 addEntry:

void addEntry(int hash, K key, V value, int bucketIndex) {

        Entry<K,V> e = table[bucketIndex];

        table[bucketIndex] = new Entry<K,V>(hash, key, value, e);

        if (size++ >= threshold)

                resize(2 * table.length);

}

table[bucketIndex]假如被两个线程同时获取就会导致某一进程的数据丢失。

ps:

protected Entry(int hash,K key,V value,Entry<K,V>next)    {

        this.hash=hash;

        this.key=key;

        this.value=value;

         this.next=next;//从Entry构造函数看是不是可以说明是从头结点插入的呢?

}


2、删除会调用removeEntryForKey:

final Entry<K,V> removeEntryForKey(Object key) {

        int hash = (key == null) ? 0 : hash(key.hashCode());

        int i = indexFor(hash, table.length);

        Entry<K,V> prev = table[i];//取到头结点

        Entry<K,V> e = prev;

        while (e != null) {

            Entry<K,V> next = e.next;//下一个结点

            Object k;

            if (e.hash == hash &&  ((k = e.key) == key || (key != null && key.equals(k)))) {

                modCount++;

                size--;

                if (prev == e)

                    table[i] = next;

                else

                    prev.next = next;

                e.recordRemoval(this);

                return e;

            }

            prev = e;

            e = next;

        }

        return e;

    }

与put一致也会获取table[i]头结点。

3、当键值对数量超过门限值时会调用resize操作:

void resize(int newCapacity) {

        Entry[] oldTable = table;

        int oldCapacity = oldTable.length;

        if (oldCapacity == MAXIMUM_CAPACITY) {

            threshold = Integer.MAX_VALUE;

            return;

        }

        Entry[] newTable = new Entry[newCapacity];//产生一个新的数组

        transfer(newTable);

        table = newTable;

        threshold = (int)(newCapacity * loadFactor);

}

当两个线程同时rezise就不知道是哪个数组被留下了。

pps:今天还有许多问题需要闭环,比如hashcode和equals的关系(又忘了)。。。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容