首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

确定'put‘操作是否在ConcurrentHashMap的putIfAbsent方法中实际执行?

在ConcurrentHashMap的putIfAbsent方法中,如果指定的键不存在,则会执行put操作。put操作会将指定的键值对插入到ConcurrentHashMap中。如果指定的键已经存在,则不会执行put操作,返回已存在的值。

ConcurrentHashMap是Java中线程安全的哈希表实现,它支持高并发的读写操作。putIfAbsent方法是ConcurrentHashMap提供的一个原子操作,用于在键不存在时插入键值对。该方法的执行过程如下:

  1. 首先,ConcurrentHashMap会根据键的哈希值确定该键应该存储在哪个桶中。
  2. 然后,ConcurrentHashMap会尝试获取该桶的锁,以确保并发操作的安全性。
  3. 如果指定的键不存在于该桶中,ConcurrentHashMap会执行put操作,将键值对插入到该桶中,并返回null。
  4. 如果指定的键已经存在于该桶中,ConcurrentHashMap不会执行put操作,直接返回已存在的值。

ConcurrentHashMap的putIfAbsent方法适用于需要在多线程环境下插入键值对的场景,可以保证插入操作的原子性和线程安全性。

腾讯云提供了一系列与云计算相关的产品,其中包括云服务器、云数据库、云存储等。对于ConcurrentHashMap的应用场景,可以考虑使用腾讯云的云服务器来搭建高并发的应用程序,使用云数据库来存储数据,使用云存储来存储大量的文件和对象。

腾讯云云服务器产品介绍链接:https://cloud.tencent.com/product/cvm 腾讯云云数据库产品介绍链接:https://cloud.tencent.com/product/cdb 腾讯云云存储产品介绍链接:https://cloud.tencent.com/product/cos

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

juc系列-ConcurrentHashMap

我们知道基于散列容器是通过元素hashCode值来确定元素容器索引,那么ConcurrentHashMap定位一个元素至少需要两步: 定位segment 定位HashEntry segmentShift...put方法,首先进行加锁操作,tryLock失败后并不会按照常规思路阻塞当前线程,而是执行scanAndLockForPut方法,下面重点分析下这个方法做了什么工作?...还实现了类似于自旋锁功能,防止执行put操作线程频繁阻塞,这些优化都提升了put操作性能。...肯定不行,并发环境,这样得到结果并不准确。对所有segment加锁再求和?这样做结果肯定正确,但是这违背了ConcurrentHashMap设计初衷,并发环境要有良好变现。...考虑这么一种情况,当A线程执行clear方法时,已经将segments[0]对象清空了,此时B线程执行put(key,value)方法,如果key散列到segments[0]上,那么A执行完后容器还有元素

33730

ConcurrentHashMap使用示例

实际上,线程安全容器,特别是Map,应用场景没有想象多,很多情况下一个业务会涉及容器多个操作,即复合操作,并发执行时,线程安全容器只能保证自身数据不被破坏,但无法保证业务行为是否正确。...举个例子:统计文本单词出现次数,把单词出现次数记录到一个Map,代码如下: private final Map wordCounts = new ConcurrentHashMap...1L : oldValue + 1; wordCounts.put(word, newValue); return newValue; } 如果多个线程并发调用这个increase()方法,...对于这个应用,这不算问题,创建AtomicLong成本不高,而且只添加不存在词是出现。...最后再补充一下,如果真要实现前面说统计单词次数功能,最合适方法是Guava包AtomicLongMap;一般使用ConcurrentHashMap,也尽量使用GuavaMapMaker或cache

2.6K90
  • HashMap,HashTable,ConcurrentHashMap面试总结!!!

    对象offset偏移地址对应object型field值,支持volatile load语义,即:让缓存数据失效,重新从主内存加载数据 (2)put()方法   ①需要获取数组上Node时同样使用...但是,因为多个线程用相同key调用时,很可能会覆盖相互结果,造成记录次数比实际出现次数少。...当然可以用锁解决这个问题,但是也可以使用ConcurrentMap定义方法: V putIfAbsent(K key, V value) 如果key对应value不存在,则put进去,返回null...,不同地方有不同用途,其值也不同,所代表含义也不同 负数代表正在进行初始化或扩容操作 -1代表正在初始化 -N 表示有N-1个线程正在进行扩容操作 正数或0代表hash表还没有被初始化,这个数值表示初始化或下一次进行扩容大小...size + 1 这里整个put操作已经完成。

    56620

    90%面试都会问到知识点,你看会吗?

    对象offset偏移地址对应object型field值,支持volatile load语义,即:让缓存数据失效,重新从主内存加载数据 (2)put()方法   ①需要获取数组上Node时同样使用...但是,因为多个线程用相同key调用时,很可能会覆盖相互结果,造成记录次数比实际出现次数少。...当然可以用锁解决这个问题,但是也可以使用ConcurrentMap定义方法: V putIfAbsent(K key, V value) 如果key对应value不存在,则put进去,返回null...,不同地方有不同用途,其值也不同,所代表含义也不同 负数代表正在进行初始化或扩容操作 -1代表正在初始化 -N 表示有N-1个线程正在进行扩容操作 正数或0代表hash表还没有被初始化,这个数值表示初始化或下一次进行扩容大小...size + 1 这里整个put操作已经完成。

    48710

    【小家java】JavaFuture模式衍生出来高级应用---自己手写一个数据库连接池

    虽然ConcurrentHashMapput方法只会加入其中一个,但还是生成了2个多余连接。如果是真正数据库连接,那会造成极大资源浪费。...我们只需要让一个线程执行FutureTaskrun方法,其它线程只执行get方法就好了。...c","d")); //c 注意此处返回值为c而不是d } 由此课件,mapput/putIfAbsent成功后返回值,返回是oldValue,而不是新值。...第一个线程执行pool.putIfAbsent方法后返回null,然后connectionTask被赋值,接着就执行run方法去创建连接,最后get。...后面的线程执行pool.putIfAbsent方法不会返回null,就只会执行get方法并发环境下,通过FutureTask作为中间转换,成功实现了让某个方法只被一个线程执行

    87720

    深入理解JavaConcurrentHashMap:原理与实践

    1.2 并发操作方法 ConcurrentHashMap提供了一些用于并发操作方法,如putIfAbsent()、replace()、remove()等。...首先,ConcurrentHashMap所有操作都是线程安全,但如果你需要执行复合操作(例如,先检查一个键是否存在,然后根据结果进行更新操作),那么就需要额外同步措施来保证这些操作原子性。...源码扩容操作如下:Java 8ConcurrentHashMap,rehashing过程主要在transfer方法实现,这个方法ConcurrentHashMap需要扩容时被调用。...高并发环境下,由于多个线程可能同时 ConcurrentHashMap 中进行插入、删除和更新操作,计算出元素总数可能与实际元素总数有一定偏差。...需要处理并发访问场景ConcurrentHashMap是一个非常实用工具。 实际应用,我们需要根据具体场景和需求来选择合适数据结构。

    26610

    使用ConcurrentHashMap实现高效缓存框架

    其实在调用cache::get和cache::put方法之间进行了一些计算,当一个线程执行了cache::get方法之后得到了空result,其会执行高额Computable::compute方法,...,而值则是一个个FutureTask对象,真正计算放到了一个Callable对象调用FutureTask::run方法时,是实际执行了Computable::compute方法。...Memorizer3对于缓存实现几乎是完美的,但是其还是存在重复计算缺陷,即当一个线程cache未找到结果,其创建了FutureTask对象并将其放入cache,然后执行run方法计算结果同时...ConcurrentHashMap中提供了一个方法V putIfAbsent(K key, V value),其是一个原子若不存在则添加方法,并且其会返回当前Map已经存在value值,若没有则返回...::putIfAbsent方法,假设两个线程传入了同样参数,并且都创建了一个FutureTask对象,一个线程获得了cache执行权限执行了cache::putIfAbsent()方法,并且返回了一个

    1.4K20

    java构建高效结果缓存

    使用HashMap 缓存通常用法就是构建一个内存中使用Map,在做一个长时间操作比如计算之前,先在Map查询一下计算结果是否存在,如果不存在的话再执行计算操作。...方法实际上调用了封装Calculatorcalculate方法。...虽然这样设计能够保证程序正确执行,但是每次只允许一个线程执行calculate操作,其他调用calculate方法线程将会被阻塞,多线程执行环境这会严重影响速度。...FutureTask表示一个计算过程,我们可以通过调用FutureTaskget方法来获取执行结果,如果该执行正在进行,则会等待。 下面我们使用FutureTask来进行改写。...这个时候,我们可以借助于ConcurrentHashMap原子性操作putIfAbsent来重写上面的类: @Slf4j public class MemoizedCalculator4

    1.5K30

    Java集合--ConcurrentMap

    :与原有put方法不同是,putIfAbsent方法如果插入key相同,则不替换原有的value值; remove:与原有remove方法不同是,新remove方法增加了对value判断,如果要删除...来说,我们更关注Map本身操作并发情况下是如何实现数据安全。...,同时A、B两个线程走到createEntry()方法,并且这两个线程插入元素hash值相同,bucketIndex值也相同,那么无论A线程先执行,还是B线程先被执行,最终都会2个元素先后向链表头部插入...public synchronized V put(K key, V value) {...} } 通过上述代码,可以清晰看出,HashTable主要操作方法上都加了synchronized锁以来保证线程安全...多线程,每一个Segment对象守护了一个HashEntry数组,当对ConcurrentHashMap元素修改时,获取到对应Segment数组角标后,都会对此Segment对象加锁,之后再去操作后面的

    1.1K90

    日常工作中最容易犯几个并发错误

    走过路过不要错过 点击蓝字关注我们 前言 列举大家平时在工作中最容易犯几个并发错误,都是实际项目代码中看到鲜活例子,希望对大家有帮助。...} } } 因为desc是全局变量,并发情况下,请求getDescByUserType方法,得到可能并不是你想要结果。...那么怎么解决这个问题呢,可以考虑用SET key value NX EX max-lock-time ,它是一种 Redis 实现锁方法,是原子性操作,不会像以上代码分两步执行,先set再expire...客户端执行以上命令: 如果服务器返回 OK ,那么这个客户端获得锁。 如果服务器返回 NIL ,那么客户端获取锁失败,可以稍后再重试。...= null){ v = old; } } 可以考虑使用putIfAbsent解决这个问题 (1)如果key是新记录,那么会向map添加该键值对,并返回null

    31810

    java并发编程工具类JUC第八篇:ConcurrentHashMap

    由于Java程序员常用HashMap操作方法不是同步,所以多线程环境下会导致存取操作数据不一致问题,Map接口另一个实现类Hashtable 虽然是线程安全,但是多线程下执行效率很低。...为了解决这个问题,java 1.5版本引入了线程安全集合类ConcurrentMap。...向ConcurrentHashMap插入元素 put(K,V) - 向map插入key/value 键值对数据 putAll(map) - 把另一个map所有entries插入到当前map putIfAbsent...(K,V) - 向map插入key/value 键值对数据,如果该键值对keymap不存在则插入数据,否则不做操作。...ConcurrentHashMap(); // 使用put()方法插入数据 evenNumbers.put("Two", 2); evenNumbers.put

    36930

    日常工作中最容易犯几个并发错误

    前言 列举大家平时在工作中最容易犯几个并发错误,都是实际项目代码中看到鲜活例子,希望对大家有帮助。...是全局变量,并发情况下,请求getDescByUserType方法,得到可能并不是你想要结果。...那么怎么解决这个问题呢,可以考虑用SET key value NX EX max-lock-time ,它是一种 Redis 实现锁方法,是原子性操作,不会像以上代码分两步执行,先set再expire...客户端执行以上命令: 如果服务器返回 OK ,那么这个客户端获得锁。 如果服务器返回 NIL ,那么客户端获取锁失败,可以稍后再重试。...= null){ v = old; } } 可以考虑使用putIfAbsent解决这个问题 (1)如果key是新记录,那么会向map添加该键值对

    31310

    Java 8并发教程:原子变量和ConcurrentMap

    当您可以安全地多个线程上并行执行操作时,操作是原子,而不使用我以前教程中所示synchronized关键字或锁。...至少对于 ConcurrentHashMap ,该方法实现是线程安全,就像 put() ,所以你不必同步从不同线程并发访问映射: String value = map.putIfAbsent("c3...此外,最重要实现ConcurrentHashMap已经通过几种新方法进一步增强,以地图上执行并行操作。...例如,如果通过阈值为500,并且地图实际大小为499,则操作将在单个线程上顺序执行。在下面的例子,我们使用一个阈值来总是强制执行并行执行来进行演示。...请记住,ConcurrentHashMap是无序。搜索功能不应取决于地图实际处理顺序。如果地图多个条目与给定搜索函数匹配,则结果可能是非确定

    69820

    面试阿里被P8质问:ConcurrentHashMap真的线程安全吗?

    开发人员误以为使用ConcurrentHashMap就不会有线程安全问题,于是不加思索地写出了下面的代码:每一个线程代码逻辑先通过size方法拿到当前元素数量,计算ConcurrentHashMap...目前还需要补充多少元素,并在日志输出了这个值,然后通过putAll方法把缺少元素添加进去。...ConcurrentHashMap对外提供能力限制: 使用不代表对其多个操作之间状态一致,是没有其他线程操作。...性能,优化后: [45niism1jb.png] ConcurrentHashMap原子性方法computeIfAbsent做复合逻辑操作,判断K是否存在V,若不存在,则把Lambda运行后结果存入...不存在时候,putIfAbsent返回null,小心空指针,而computeIfAbsent返回计算后值 当Key不存在时候,putIfAbsent允许put null进去,而computeIfAbsent

    1.2K32

    3秒搞定ConcurrentHashMap

    基本思想就是不断地去比较当前内存变量值与你指定一个变量值(预期值)是否相等,如果相等,则接受你指定修改值(新值),否则证明已经有别的线程修改过该变量值,拒绝你操作。...ConcurrentHashMap线程安全,ConcurrentHashMap,大量使用了U.compareAndSwapXXX方法,这个方法是利用一个CAS算法实现无锁化修改值操作,他可以大大降低锁代理性能消耗...同时,ConcurrentHashMap还定义了三个原子操作,用于对指定位置节点进行操作。这三种原子操作被广泛使用在ConcurrentHashMapget和put方法。...我们可以发现JDK8ConcurrentHashMap实现使用是锁分离思想,只是锁住是一个node,而锁住Node之前操作是基于volatile和CAS之上无锁并且线程安全。...ConcurrentHashMap扩容机制 ConcurrentHashMap处理rehash时候,并不会重新计算每个keyhash值,而是利用了一种很巧妙方法

    58630

    ConcurrentHashMap实现原理

    前言 在这篇文章对属性介绍比较多:HashMap实现原理 HashMap不是线程安全多线程环境下可以使用Hashtable和ConcurrentHashMap,Hashtable实现线程安全方式是用...synchronized修饰方法,如get和put方法都是用synchronized修饰,使用是对象锁,这样会导致线程1get元素(或者put元素)时,线程2不能get元素和put元素,竞争激烈时候会出现严重性能问题...将put操作代理给Segment 将value插入定位到SegmentHashEntry数组,如果key已经存在,则返回oldValue,否则返回null 注意看最后一个参数,put方法调用是s.put...(key, hash, value, false),即key相等时候,put会用newValue替换oldValue 而putIfAbsent方法调用是s.put(key, hash, value...Integer.MAX_VALUE : size; } 计算ConcurrentHashMapsize时,因为并发操作缘故,还有可能一直插入数据,可能导致计算返回 size和实际size有相差

    42610

    死磕 java集合之ConcurrentHashMap源码分析(三)

    ; (2)如果桶第一个元素就是该找元素,直接返回; (3)如果是树或者正在迁移元素,则调用各自Node子类find()方法寻找元素; (4)如果是链表,遍历整个链表寻找元素; (5)获取元素没有加锁...-1,表示正在进行初始化; (7)sizeCtl = 0,默认值,表示后续真正初始化时候使用默认容量; (8)sizeCtl > 0,初始化之前存储是传入容量,初始化或扩容后存储是下一次扩容门槛...(18)查询操作是不会加锁,所以ConcurrentHashMap不是强一致性; (19)ConcurrentHashMap不能存储key或value为null元素; 彩蛋——值得学习技术 ConcurrentHashMap...(key, value); }} 这样的话就没办法使用putIfAbsent()方法了。...()操作,而是还有其它业务操作,之后才是put(),比如下面这样,这该怎么办呢?

    38810

    ConcurrentHashMap详解,以及各map相互比较

    :put方法源码逻辑 1.判断Node[]数组是否初始化,没有则进行初始化操作 2.通过hash定位数组索引坐标,是否有Node节点,如果没有则使用CAS进行添加(链表头节点),添加失败则进入下次循环...putIfAbsent */ //onlyIfAbsent意思是put一个KV时,如果K已经存在什么也不做则返回null //如果不存在则put操作后返回V值 final V putVal(K key...关于ConcurrentHashMap主要注意地方 1.size()方法和mappingCount方法异同,两者计算是否准确?   ...应该使用此方法而不是size(),因为ConcurrentHashMap可能包含映射数多于可以表示为int映射。返回值是估计值; 如果有并发插入或删除,实际计数可能会有所不同。...2.CouncurrentHahsMap并发扩容问题 CouncurrentHahsMap添加元素时候会判断是否有线程扩容,如果有,它会调用一个helpTransfer()方法,在这个方法里会重新确认一下

    19720

    缓存简单实现

    //此文基于《Java并发编程实践》 我们都知道应用程序合理地使用缓存,能更快访问我们之前计算结果,从而提高吞吐量。例如Redis和Memcached基于内存数据存储系统等。...可见使用synchronized同步方法如此大粒度同步必然会带来并发性降低,因为每次只有一个线程执行compute方法,其余线程只能排队等待。...2.利用并发容器ConcurrentHashMap 第1种方法能实现缓存,且能实现线程安全缓存,不过带来问题就是并发性降低。我们使用并发包ConcurrentHashMap并发容器。...,但这并不算是最完美的实现,compute方法中出现了if复合操作,也就是说期间还是很有可能出现如同ConcurrentHashMap一样重复计算,只是概率降低了而已。...幸好,ConcurrentHashMap为我们提供了putIfAbsent原子方法,从而完美的避免了这个问题。

    72890
    领券