关于 synchronized 关键字的疑问 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
MeloForsaken
V2EX    程序员

关于 synchronized 关键字的疑问

  •  
  •   MeloForsaken 2020-10-12 22:38:39 +08:00 2287 次点击
    这是一个创建于 1910 天前的主题,其中的信息可能已经有所发展或是发生改变。

    在许多文章中看到 synchronized 会有多种锁的类型,只有到最后才会升级到重量级锁,但是在 JDK1.8 下随便用个 synchronized 就能看到 monitor.enter 和 monitor.exit 字节码指令,这不就矛盾了吗?那么前面的轻量级锁、自旋锁等等去哪儿了?还是说 monitor 不是重量级锁?

    8 条回复    2020-10-13 11:15:02 +08:00
    looplj
        1
    looplj  
       2020-10-12 22:58:46 +08:00   1
    这种锁不是字节码级别的,是 JVM 内部实现,没有暴露给字节码。
    其实,偏向锁用处不是那么的大,现在已经有 JEP 去删除偏向锁了。
    9LCRwvU14033RHJo
        2
    9LCRwvU14033RHJo  
       2020-10-12 23:15:20 +08:00
    许多文章?什么文章啊?
    geelaw
        3
    geelaw  
       2020-10-12 23:30:04 +08:00 via iPhone
    楼主看的文章里说 synchronized 锁有多种状态且会变化,然后又问 monitor (管程)锁是什么,显然是没有理解 synchronized 的原理、Java 对象结构、什么是 Java 对象的管程。

    Java 对象的管程 = 可以用 synchronized 访问的那个同步机制,所谓 synchronized 不过是访问 monitor 的语法机制,而“synchronized 所用的锁会变化”就是说 Java 对象管程里的锁会变化。
    yanyueio
        4
    yanyueio  
       2020-10-12 23:30:28 +08:00
    #1 正解,但谈底层的时候,一定要注明是哪个 jdk 版本,什么版本的 jdk,最好看一下其提交 commit id,甚至是什么虚拟机执行的,编译是什么 javac 工具。(普通最好)


    首先 synchronized 本来就有隐式监视器实现,免除你手动加锁的那些比如 reenter lock, unlock()。
    synchronized 是排他锁,所以字节码可以看到监视器,很正常( java 内部还有哪?就是解释执行字节码啊)绑定到当前对象上,相对的那些可重入锁,自旋锁等轻量锁由于引入了更多功能才不一定会有 monitor 这类监视器。比如我们在 C++ 里面就会利用变量作用域来代替锁,作用域结束,自动解锁(因为对象被收走啦)。

    monitor 只是一种实现锁的机制(绑定到"字节码对象"上),可算作排他锁(重量级)锁实现额手段。

    “只有到最后才会升级到重量级锁” --- 最后?喵喵喵。

    歪嘴,我理解楼主所说 "最后" 是指运行阶段,而不是编译时。坏笑。
    MeloForsaken
        5
    MeloForsaken  
    OP
       2020-10-13 09:37:40 +08:00
    @ZSeptember @geelaw @user8341 @yanyueio
    "事实上,只有在 JDK1.6 之前,synchronized 的实现才会直接调用 ObjectMonitor 的 enter 和 exit,这种锁被称之为重量级锁。"
    这句话是不是有点问题,如果说重量级锁才会有 enter 和 exit 字节码指令的话,那为什么 JDK1.8 下随便写个 synchronized 代码块的 demo 反编译后的字节码指令里面会有 enter 和 exit,这不表示 synchronized 默认使用重量级锁?还是说偏向锁、轻量级锁也会涉及到 enter 和 exit 指令?
    谢谢!!!
    geelaw
        6
    geelaw  
       2020-10-13 10:18:27 +08:00 via iPhone   1
    @MeloForsaken #5 请你 cite 内容的时候给出链接。
    另外你似乎没有搞懂 object monitor 和 ObjectMonitor 和 monitorenter 的关系。

    Object monitor 是英文词组,意思是对象的管程,这是一个概念。
    ObjectMonitor 是 JDK 源代码里类的名字,它是 object monitor 这个概念的是一个实现。
    monitorenter 是一个 Java 字节码指令,它的意思是“进入对象的管程”,即它的作用对象是 object monitor 这个概念,至于是调用 ObjectMonitor 的方法还是怎么样,那是实现细节,取决于 object monitor 的状态。

    要理解 Java 的同步机制,首先需要理解不特定于 Java 的同步机制。你问的问题似乎是没有搞清楚同步机制(管程)、Java 同步机制( Java 对象的管程、monitorenter )、Java 同步机制的实现( ObjectMonitor 类)之间的关系。

    换言之,你所谓的“重量级锁”是 ObjectMonitor,一个 Java 对象的管程可能是用 ObjectMonitor 实现的,也可能是用别的代码实现的,而且同一个对象的管程可以一会儿不用 ObjectMonitor 一会儿用,而 monitorenter 的实际效果是根据对象管程的实现决定的。
    MeloForsaken
        7
    MeloForsaken  
    OP
       2020-10-13 10:43:43 +08:00
    @geelaw 理解了,感谢
    9LCRwvU14033RHJo
        8
    9LCRwvU14033RHJo  
       2020-10-13 11:15:02 +08:00
    @MeloForsaken

    我觉得如果真的真的很想搞清楚的话,可以去看看 Hotspot 的源码。

    hg.openjdk.java.net/jdk8u/jdk8u/hotspot/file/tip/src/share/vm/interpreter/bytecodeInterpreter.cpp#l1816
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5403 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 25ms UTC 07:29 PVG 15:29 LAX 23:29 JFK 02:29
    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