本博客日IP超过2000,PV 3000 左右,急需赞助商。
极客时间所有课程通过我的二维码购买后返现24元微信红包,请加博主新的微信号:xttblog2,之前的微信号好友位已满,备注:返现
受密码保护的文章请关注“业余草”公众号,回复关键字“0”获得密码
所有面试题(java、前端、数据库、springboot等)一网打尽,请关注文末小程序
腾讯云】1核2G5M轻量应用服务器50元首年,高性价比,助您轻松上云
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的使用场景
-
public synchronized void method1
锁住的是该对象,类的其中一个实例,当该对象(仅仅是这一个对象)在不同线程中执行这个同步方法时,线程之间会形成互斥。达到同步效果,但如果不同线程同时对该类的不同对象执行这个同步方法时,则线程之间不会形成互斥,因为他们拥有的是不同的锁。 -
synchronized(this){ //TODO }
同一 -
public synchronized static void method3
锁住的是该类,当所有该类的对象(多个对象)在不同线程中调用这个static同步方法时,线程之间会形成互斥,达到同步效果,但如果多个线程同时调用method1,method3,则不会引互斥,具体讲看最后讲解。 -
synchronized(Test.class){ //TODO}
同三 -
synchronized(o) {}
这里面的o可以是一个任何Object对象或数组,并不一定是它本身对象或者类,谁拥有o这个锁,谁就能够操作该块程序代码。
参考资料
- https://blogs.oracle.com/dave/entry/biased_locking_in_hotspot
- http://www.javaworld.com/article/2076971/java-concurrency/how-the-java-virtual-machine-performs-thread-synchronization.html
- http://f.dataguru.cn/thread-472518-1-1.html
最后,欢迎关注我的个人微信公众号:业余草(yyucao)!可加作者微信号:xttblog2。备注:“1”,添加博主微信拉你进微信群。备注错误不会同意好友申请。再次感谢您的关注!后续有精彩内容会第一时间发给您!原创文章投稿请发送至532009913@qq.com邮箱。商务合作也可添加作者微信进行联系!
本文原文出处:业余草: » java synchronized 详解