V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
bingoshe
V2EX  ›  Java

concurrentHashMap 为什么是 CAS+Sychronized 保障线程安全?

  •  
  •   bingoshe · 2021-04-20 18:21:37 +08:00 · 2237 次点击
    这是一个创建于 1321 天前的主题,其中的信息可能已经有所发展或是发生改变。
    为什么不是 CAS+CAS Sychronized+Sychronized?
    7 条回复    2021-04-25 16:55:00 +08:00
    VinsonGuo
        1
    VinsonGuo  
       2021-04-20 18:28:42 +08:00
    cas 的性能大于 synchronized,但是 cas 可能会失败(默认应该是自旋 10 次),在失败的情况下再使用 sync

    全部用 sync 锁的话,性能太差了
    Leviathann
        2
    Leviathann  
       2021-04-20 19:11:46 +08:00 via iPhone
    cas 在高并发的时候经常比较失败
    性能还不如上锁
    fareware
        3
    fareware  
       2021-04-20 19:51:48 +08:00
    这不是一面八股文基础题吗,阿里就喜欢这个
    ccde8259
        4
    ccde8259  
       2021-04-20 21:25:13 +08:00 via iPhone
    put/set 用 synchronized 锁头节点不用 CAS,可能考虑原因是对整个链表 /红黑树进行 CAS 代价太大。需要把链表 /红黑树 deep copy 然后进行 compare 和 swap 操作,失败再拷一遍?
    rehash 用 CAS 不用 synchronized,可能考虑原因是 CAS 抢占失败代表已经有线程领过了这个任务,没有必要再尝试 CAS 。这里锁并不需要真正获取到,比起 synchronized 进去发现任务没了代价更低。
    hfc
        5
    hfc  
       2021-04-21 11:01:14 +08:00
    synchronized 是悲观锁,CAS 是乐观锁,乐观锁适用于竞争较少的情况下。
    ConcurrentHashMap 用 synchronized 的地方是锁住 table 上的某个 Node 头节点吧,这个 Node 还会通过 next 连接成链表,那么在链表较长时,其上发生的竞争几率就会比较高,这个时候估计使用悲观锁会比乐观锁效率更高。
    4kingRAS
        6
    4kingRAS  
       2021-04-21 17:51:02 +08:00
    eric96
        7
    eric96  
       2021-04-25 16:55:00 +08:00
    可以看下 put 方法,只有在头节点为 null 时候,才是 cas 放入新节点。
    否则是对当前节点加锁的
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2602 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 10:52 · PVG 18:52 · LAX 02:52 · JFK 05:52
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.