hashmap在多线程下数据丢失问题

我们都知道hashmap是非线程安全的。什么是非线程安全呢?个人理解,就是在多线程环境下,一个线程对值做变更时,不会立即同步到其他线程,这时候其他线程获取该值的话就是取到旧值,如果在此基础上进行计算的话就会得到错误的结果。这点应该和java的内存模型有关,java内存分为工作内存和主内存。如图下所示(图为网上所找,侵删):java所有的变量都存储在主内存中,工作内存保存的是主内存的副本,线程所有对变量的操作都是在工作内存中完成的,无法直接操作主内存。而线程写变量到工作内存,再由工作内存同步到主内存,这
摘要由CSDN通过智能技术生成

我们都知道hashmap是非线程安全的。什么是非线程安全呢?个人理解,就是在多线程环境下,一个线程对值做变更时,不会立即同步到其他线程,这时候其他线程获取该值的话就是取到旧值,如果在此基础上进行计算的话就会得到错误的结果。

这点应该和java的内存模型有关,java内存分为工作内存主内存。如图下所示(图为网上所找,侵删):
图为网上所找,侵删
java所有的变量都存储在主内存中,工作内存保存的是主内存的副本,线程所有对变量的操作都是在工作内存中完成的,无法直接操作主内存。而线程写变量到工作内存,再由工作内存同步到主内存,这一过程并不是原子的,所以有可能你其中一个线程的对变量做了改变,但是变量的改变还没有同步到主内存,或者说其他线程没有从主内存获取到最新的值到该线程对应的工作内存的话就可能出现其他线程使用到的变量不是最新的。

基于以上两点,我们来看一下为什么多线程环境下hashmap会出现数据丢失的情况,它不是key value对应的吗?为什么key不同 还会出现数据丢失呢。下面我们来看看源码:

    public HashMap(int initialCapacity, float loadFactor) {
   
        if (initialCapacity < 0)
            throw new IllegalArgumentException("Illegal initial capacity: " +
                                               initialCapacity);
        if (initialCapacity > MAXIMUM_CAPACITY)
            initialCapacity = MAXIMUM_CAPACITY;
        if (loadFactor <= 0 || Float.isNaN(loadFactor))
            throw new IllegalArgumentException("Illegal load factor: " +
                                               loadFactor);
        this.loadFactor = loadFactor;
        this.threshold = tableSizeFor(initialCapacity);
    }

这是一段hashmap的构造方法,用来初始化负载因子和阈值。这里有个疑问,如果有小伙伴知道的话麻烦告诉我下,就是阈值的算法应该是tableSize * loadFactor,这里为什么直接赋值tableSize呢?tableSizeFor函数这里就不展开了,大概逻辑就是找到传入参数的最接近的下一个2的幂次方,举例说明就是:传入2返回2,传入3返回4。

接着再看下一段源码:

public V put(K key, V value) {
   
        return putVal(hash(key), key, value, false, true);
}

final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
                   boolean evict) {
   
        Node<K,V>[] tab; Node<K,V> p; int n, i;
        if ((tab = table) == null || (n = tab.length) == 0)
            n = (tab = resize()).length; // 1.resize为扩容方法
        if ((p = tab[i = (n - 1) & hash]) == null)
            tab[i] 
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值