北镇建设局网站,小学生做网站步骤,网站建设额,docker 做网站文章底部有个人公众号#xff1a;热爱技术的小郑。主要分享开发知识、学习资料、毕业设计指导等。有兴趣的可以关注一下。为何分享#xff1f; 踩过的坑没必要让别人在再踩#xff0c;自己复盘也能加深记忆。利己利人、所谓双赢。 面试官#xff1a;说一说synchronized的底… 文章底部有个人公众号热爱技术的小郑。主要分享开发知识、学习资料、毕业设计指导等。有兴趣的可以关注一下。为何分享 踩过的坑没必要让别人在再踩自己复盘也能加深记忆。利己利人、所谓双赢。 面试官说一说synchronized的底层实现原理
参考答案
一、synchronized作用在代码块时它的底层是通过monitorenter、monitorexit指令来实现的。 monitorenter 每个对象都是一个监视器锁monitor当monitor被占用时就会处于锁定状态线程执行monitorenter指令时尝试获取monitor的所有权过程如下 如果monitor的进入数为0则该线程进入monitor然后将进入数设置为1该线程即为monitor的所有者。如果线程已经占有该monitor只是重新进入则进入monitor的进入数加1。如果其他线程已经占用了monitor则该线程进入阻塞状态直到monitor的进入数为0再重新尝试获取monitor的所有权。 monitorexit 执行monitorexit的线程必须是objectref所对应的monitor持有者。指令执行时monitor的进入数减1如果减1后进入数为0那线程退出monitor不再是这个monitor的所有者。其他被这个monitor阻塞的线程可以尝试去获取这个monitor的所有权。 monitorexit指令出现了两次第1次为同步正常退出释放锁第2次为发生异步退出释放锁。
二、方法的同步并没有通过 monitorenter 和 monitorexit 指令来完成不过相对于普通方法其常量池中多了 ACC_SYNCHRONIZED 标示符。JVM就是根据该标示符来实现方法的同步的
当方法调用时调用指令将会检查方法的 ACC_SYNCHRONIZED 访问标志是否被设置如果设置了执行线程将先获取monitor获取成功之后才能执行方法体方法执行完后再释放monitor。在方法执行期间其他任何线程都无法再获得同一个monitor对象。
三、总结
两种同步方式本质上没有区别只是方法的同步是一种隐式的方式来实现无需通过字节码来完成。两个指令的执行是JVM通过调用操作系统的互斥原语mutex来实现被阻塞的线程会被挂起、等待重新调度会导致“用户态和内核态”两个态之间来回切换对性能有较大影响。