如下的情形,调用时是否有一定的区别
调用时,这种写法具体是怎么执行的
同步代码块使用monitorenter 和 monitorexit 指令来实现同步
同步方法并不是由 monitorenter 和 monitorexit 指令来实现同步的,而是由方法调用指令读取运行时常量池中方法的 ACC_SYNCHRONIZED 标志来隐式实现的
在JVM中,对象在内存中的布局分为三块区域:对象头、实例数据和对齐填充。详细请看:https://blog.csdn.net/javazejian/article/details/72828483. 其字节码大致如下
public synchronized void syncTask();
descriptor: ()V
//方法标识ACC_PUBLIC代表public修饰,ACC_SYNCHRONIZED指明该方法为同步方法
flags: ACC_PUBLIC, ACC_SYNCHRONIZED
Code:
stack=3, locals=1, args_size=1
从字节码中可以看出,synchronized修饰的方法并没有monitorenter指令和monitorexit指令,取得代之的确实是ACC_SYNCHRONIZED标识,该标识指明了该方法是一个同步方法,JVM通过该ACC_SYNCHRONIZED访问标志来辨别一个方法是否声明为同步方法,从而执行相应的同步调用
并没有任何区别哦。
synchronized关键字在这三种位置,编译成字节码后,真正执行时并没有不一样的。
比如我用的HostSpot 版本 javac编译,然后反编译后的代码都是这样的:
public static synchronized void a() {
}
我推荐这种写法,开源软件以及国内一些互联网公司的java规范一般鼓励这种形式。
public synchronized static int a(){}
你的第二个问题,是怎么执行的? 没太明白你的意思,你想问的是synchronized关键字是如何起作用的吗?
那么你可以去找一本java并发编程的书去看看java并发机制哦。