• 欢迎访问web前端中文站,JavaScript,CSS3,HTML5,web前端demo
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏web前端中文站吧

java synchronized 详解

JAVA web前端中文站 3年前 (2017-04-24) 1019次浏览 已收录 0个评论

synchronized 关键字简洁、清晰、语义明确,因此即使有了 Lock 接口,使用的还是非常广泛。其应用层的语义是可以把任何一个非 null 对象作为”锁”。
synchronized 在软件层面依赖 JVM,Lock 在硬件层面依赖特殊的 CPU 指令。

JVM 如何实现 synchronized

在 java 语言中存在两种内建的 synchronized 语法:synchronized 语句和 synchronized 方法。
synchronized 语句被 javac 编译成 bytecode 时,会在同步块的入口位置和退出位置分别插入 monitorenter 和 monitorexit 字节码指令。
synchronized 方法被 javac 编译成 bytecode 时,会被翻译成普通的方法调用和返回指令如:invokevirtual、areturn 指令,在 VM 字节码层面并没有任何特别的指令来实现被 synchronized 修饰的方法,而是在 Class 文件的方法表中将该方法的 access_flags 字段中的 synchronized 标志位置 1,表示该方法是同步方法并使用调用该方法的对象或该方法所属的 Class 在 JVM 的内部对象表示 Klass 做为锁对象。

hotspot 当前对 synchronized 的实现

当前的 hotspot 共有 3 种类型的锁,来实现 synchronize 的语义,之所以有 3 种,是因为这 3 种要解决的问题不同,所做的优化也不同。这 3 种锁分别为 biased locking,stack lock,infalted(ObjectMonitor).简单除暴的来讲,从轻量级上来说,biased lock 最优,inflated 最差。

synchronized 锁住的是什么

synchronized 锁定的是对象而非函数或代码。
当 synchronized 作用在方法上时,锁住的便是对象实例(this);当作用在静态方法时锁住的便是对象对应的 Class 实例,因为 Class 数据存在于永久带,因此静态方法锁相当于该类的一个全局锁;当 synchronized 作用于某一个对象实例时,锁住的便是对应的代码块。
每个对象只有一把锁(Lock)与之关联,当进行到 synchronized 语句或函数的时候,这把锁就会被当前的线程(thread)拿走,其他的(thread)再去访问的时候拿不到锁就被暂停了。
在 HotSpot JVM 实现中,锁有个专门的名字:对象监视器。

synchronized 的使用场景

  1. public synchronized void method1
    锁住的是该对象,类的其中一个实例,当该对象(仅仅是这一个对象)在不同线程中执行这个同步方法时,线程之间会形成互斥。达到同步效果,但如果不同线程同时对该类的不同对象执行这个同步方法时,则线程之间不会形成互斥,因为他们拥有的是不同的锁。
  2. synchronized(this){ //TODO }
    同一
  3. public synchronized static void method3
    锁住的是该类,当所有该类的对象(多个对象)在不同线程中调用这个 static 同步方法时,线程之间会形成互斥,达到同步效果,但如果多个线程同时调用 method1,method3,则不会引互斥,具体讲看最后讲解。
  4. synchronized(Test.class){ //TODO}
    同三
  5. synchronized(o) {}
    这里面的 o 可以是一个任何 Object 对象或数组,并不一定是它本身对象或者类,谁拥有 o 这个锁,谁就能够操作该块程序代码。

参考资料


web 前端中文站 , 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:java synchronized 详解
喜欢 (0)
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址