[ Java 八股] 为什么说 synchronized 锁是重量级的?基于 AQS 的锁在 [阻塞线程] 时,就不涉及用户态&内核态的切换了吗? - V2EX
yodhcn
V2EX    Java

[ Java 八股] 为什么说 synchronized 锁是重量级的?基于 AQS 的锁在 [阻塞线程] 时,就不涉及用户态&内核态的切换了吗?

  •  
  •   yodhcn
    yodhcn Oct 27, 2023 4569 views
    This topic created in 932 days ago, the information mentioned may be changed or developed.
    Supplement 1    Oct 27, 2023
    根据这篇文章的介绍
    https://zhuanlan.zhihu.com/p/137624149?utm_id=0

    基于 AQS 都锁的线程的阻塞、唤醒是通过工具类 java.util.concurrent.locks.LockSupport 实现的
    LockSupport.park(Object blocker) // 阻塞线程
    LockSupport.unpark(Thread thread) // 唤醒线程

    而 park 和 unpark 方法都是通过 sun.misc.UNSAFE 类中的 park 和 unpark 方法来实现的(这 2 个方法都是本地方法)

    就是不知道这两个 native 方法是怎样实现的。。。
    12 replies    2023-10-30 17:58:07 +08:00
    Leviathann
        1
    Leviathann  
       Oct 27, 2023
    虚拟线程不支持 synchronized ,会导致物理线程阻塞,你就说他重不重吧
    yodhcn
        2
    yodhcn  
    OP
       Oct 27, 2023
    @Leviathann #1
    感谢老哥的回答!
    但我还有疑问,请您解惑

    1. 我不太了解虚拟线程,从除了虚拟线程以外的角度回答,还有别的缺点吗?
    2. AQS 的锁在 [阻塞线程] 时,涉及用户态&内核态的切换吗?
    3. synchronized Moniter 锁与 AQS 在阻塞线程的方式相同吗?区别大吗?
    xxxrubyxxx
        3
    xxxrubyxxx  
       Oct 27, 2023
    1.是否涉及切换和是否使用 syscall 相关,这两个都会使用 park 挂起线程
    2. sync 和 aqs 的实现差别不太大,都是先 cas 尝试,没拿到锁再去挂起线程,去 queue 里排队
    oldking24
        4
    oldking24  
       Oct 27, 2023 via Android
    synchronized 一旦升级就不会降级吧,但是 aqs 正常都会去 cas 一下
    cxshun
        5
    cxshun  
       Oct 27, 2023
    1. synchronized 涉及到锁升级流程,并不是一来就上重量级锁,如果只是偏向锁,成本不高,根本就不涉及到内核态的切换,就算是轻量级的,也直接用 CAS 来解决;再来才是重量级的。
    2. AQS 的锁本质上是用 CAS 来实现的,这个其实就和内核态没什么太大关系了。
    hsiafan
        6
    hsiafan  
       Oct 27, 2023
    最早的时候 synchronized 直接系统调用的,哪怕加锁成功也是有上下文切换,因此说是重量级。
    1.6 之后也会先 CAS ,跟 Lock 差别不大了。
    shalk
        7
    shalk  
       Oct 27, 2023
    所以你原本的问题应该是,sync 和 reentrainlock 的区别? 1.8 下面性能区别不大
    4kingRAS
        8
    4kingRAS  
       Oct 27, 2023
    之所以说 synchronized 有进入内核态是因为用到了 mutex 系统调用,而 AQS 底层是依赖 cmpxchg 指令,不涉及内核态
    broken123
        9
    broken123  
       Oct 27, 2023
    我只晓得 Java 的所有的锁 目前都是 aqs 接口实现的 然后 aqs 的底层原理是机遇 cpu 的 cas 原理实现的 和操作系统内核无关。只和 cpu 有关系
    Jrue0011
        10
    Jrue0011  
       Oct 27, 2023   1
    网上搜了下,感觉重量级只是说当锁膨胀到最后一个阶段,如果抢不到锁会从用户态切换到内核态挂起等待,相对前面阶段的偏向锁和轻量级锁重的说法吧,而不是跟 Lock 的对比?另外就是楼上说的 1.6 之前因为没有偏向锁、轻量级锁的优化,上来就是第三个阶段。这样看的话 1.6 之前 synchronized 和 Lock 差不多,现在如果是竞争少的情况下反而 synchronized 更优。

    以 Linux 举例,synchronized 在第三阶段的 ObjectMonitor 以及 AQS 的 LockSupport.park/Unsafe.park 好像都是 CAS + futex_wait (手动狗头下,我也不知道我说的对不对,都是搜到的资料)。
    Aresxue
        11
    Aresxue  
       Oct 30, 2023   2
    都会进入内核态,只是 synchronized 的重量级锁底层是插入了 monitorenter 和 monitorexit 两个指令,以最流行的 JVM HotSpot 为例其底层使用了 mutex ( linux 下)这个非常重的锁,而对于 AQS 使用的 LockSupport 的 park 和 unpark ,其底层会使用操作系统提供的原语,如 pthread_cond_wait (对于 POSIX 线程库)或 Windows 上的 WaitForSingleObject 等来实现线程的挂起,再使用 pthread_cond_signal (对于 POSIX 线程库)或 Windows 上的 SetEvent 等来实现线程的唤醒,这些操作系统原语通常是高效的,允许线程在等待期间几乎不占用 CPU 资源,从而有效地实现了非阻塞的线程等待和唤醒。

    不过 1.8 以后性能大差不差了(很多东西也互相借鉴其实逻辑上已经高度相似),只是 AQS 系列的锁更灵活 api 更好用,如果只有上锁解锁随便用哪个。
    huang119412
        12
    huang119412  
       Oct 30, 2023   1
    你确定你没有搞错? synchronized 重量级是相对于 CAS 的。AQS 比 synchronized 重量级,synchronized 性能比基于 AQS 的同步类,性能高一个数量级,只是 AQS 更灵活一些。
    About     Help     Advertise     Blog     API     FAQ     Solana     1561 Online   Highest 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 50ms UTC 16:44 PVG 00:44 LAX 09:44 JFK 12:44
    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