Java 轻量级锁使用在无竞争场景,那么为什么还要用它? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
shangzhanyu
V2EX    Java

Java 轻量级锁使用在无竞争场景,那么为什么还要用它?

  •  
  •   shangzhanyu 2020-11-30 17:54:11 +08:00 4163 次点击
    这是一个创建于 1832 天前的主题,其中的信息可能已经有所发展或是发生改变。

    无竞争场景不用锁不就可以了?为什么要多此一举呢?

    第 1 条附言    2020-12-02 13:47:21 +08:00

    花了一天时间按照层次整理了一下锁相关的内容

    • Java:java.util.concurrent包、synchroized
    • jvm:重入锁、cas、自适应锁、偏向锁 -> 轻量级锁 -> 重量级锁
    • 操作系统:互斥量、信号量、原子性、自旋锁、大内核锁、RCU、读/写锁
    • 硬件:
      • 单核cpu:原子性指令和指令集、总线锁、缓存锁
      • 多核cpu:缓存一致性协议MESI
    22 条回复    2020-12-01 20:34:55 +08:00
    Jooooooooo
        1
    Jooooooooo  
       2020-11-30 17:55:36 +08:00
    你完全理解错了

    无竞争是事后才知道的
    shangzhanyu
        2
    shangzhanyu  
    OP
       2020-11-30 18:00:27 +08:00
    @Jooooooooo 怎么讲?
    ApachW
        3
    ApachW  
       2020-11-30 18:11:07 +08:00
    应该是开始没并发,线程一个执行完了过了会才来一个,这时候是轻量锁,然后程序跑着跑着并发来了,锁就升级了
    liuch
        4
    liuch  
       2020-11-30 18:21:49 +08:00
    使用锁的目的是为了保证竞争下面的数据安全,这个是大前提。
    但是在某些场景下,竞争可能不存在或者不激烈。这种情况下,使用重量级锁性能不佳,也没有必要
    轻量级锁 是优化处理这种情况。后面可能会有的 线程的竞争,就会有锁升级的情况发生。
    shangzhanyu
        5
    shangzhanyu  
    OP
       2020-11-30 18:31:29 +08:00
    @ApachW 那直接使用互斥锁不是更好吗
    hdbzsgm
        6
    hdbzsgm  
       2020-11-30 18:34:39 +08:00
    @shangzhanyu 开销 /性能
    wuketidai
        7
    wuketidai  
       2020-11-30 18:53:31 +08:00
    乐观锁?
    SuperManNoPain
        8
    SuperManNoPain  
       2020-11-30 19:02:58 +08:00
    不用切换到内核态,maybe
    kkkkkrua
        9
    kkkkkrua  
       2020-11-30 19:17:47 +08:00
    你加了锁之后,这个锁是肯定存在的,这是前提
    然后是,存在后,因为没竞争,所以此时的锁是偏向 /轻量锁
    后面才是有竞争后,会锁升级。
    不知道这么讲你理解不
    kkkkkrua
        10
    kkkkkrua  
       2020-11-30 19:20:22 +08:00
    @kkkkkrua #9 当然,反过来讲,经过逃逸分析后,会锁消除的
    nicoley
        11
    nicoley  
       2020-11-30 20:23:11 +08:00
    @shangzhanyu 直呼好家伙!你用互斥锁考虑过系统整体的并发吗?
    jtchris
        12
    jtchris  
       2020-11-30 20:44:53 +08:00   1
    偏向锁没法在应用中吧(至少我不会...),是 JVM 为了优化性能搞得。你加了锁,但是程序实际运行中发现,就一个线程访问,并没有其它线程来竞争,为了提高性能就不搞同步那些了。
    比如你去饭馆买饭,收银员给你发了号码,服务员叫号上菜,当就你一个顾客时,服务员就没叫号直接给你端上来了,省了他叫号和你回答的步骤,提高了上菜速度。
    JsonTu
        13
    JsonTu  
       2020-11-30 23:01:20 +08:00 via iPhone
    @jtchris 这个比喻到位
    goodboy95
        14
    goodboy95  
       2020-12-01 09:10:27 +08:00
    轻量级锁对于 1 个线程来说确实等于没有锁啊,人家自旋的是第二个线程
    nicoley
        15
    nicoley  
       2020-12-01 09:54:44 +08:00
    在实际场景中,你不可以预测后面有没有线程来抢夺资源吧,如果后面随着线程竞争加剧还会出现锁升级等等。所以用轻量级锁的目的就是防微杜渐。
    securityCoding
        16
    securityCoding  
       2020-12-01 10:08:38 +08:00
    一楼说的狠明白 ,一开始你怎么知道有没有狗子跟你抢东西吃呢
    shangzhanyu
        17
    shangzhanyu  
    OP
       2020-12-01 10:09:32 +08:00
    @nicoley 这么解释能理解了,为了防止可能出现的竞争场景,一般在什么场景下使用?
    shangzhanyu
        18
    shangzhanyu  
    OP
       2020-12-01 10:10:46 +08:00
    @securityCoding 比如什么场景呢?
    securityCoding
        19
    securityCoding  
       2020-12-01 10:21:32 +08:00
    @shangzhanyu 当锁是偏向锁的时候,被另外的线程所访问,偏向锁就会升级为轻量级锁,其他线程会通过自旋的形式尝试获取锁,不会阻塞,从而提高性能。
    securityCoding
        20
    securityCoding  
       2020-12-01 10:23:43 +08:00
    @shangzhanyu 抱歉看错了。
    偏向锁是指一段同步代码一直被一个线程所访问,那么该线程会自动获取锁,降低获取锁的代价。
    在大多数情况下,锁总是由同一线程多次获得,不存在多线程竞争,所以出现了偏向锁。其目标就是在只有一个线程执行同步代码块时能够提高性能。

    从这篇文章( https://tech.meituan.com/2018/11/15/java-lock.html )看来的,美团的技术文章写的都挺不错的。
    shangzhanyu
        21
    shangzhanyu  
    OP
       2020-12-01 13:09:58 +08:00
    @jtchris 意思是这些是 jvm 对锁的优化,应用中没有对应的使用方式是吗?
    jtchris
        22
    jtchris  
       2020-12-01 20:34:55 +08:00
    @shangzhanyu 这是 JVM 源码的实现,JDK 是没有这类 API 的。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2565 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 25ms UTC 10:30 PVG 18:30 LAX 02:30 JFK 05:30
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86