同步基于JVM实现。它通过基于jvm.Methods输入和退出监视器对象来实现方法同步和代码块同步。使用MonitorEnter和MonitoreXIT指令实现代码块同步。该方法同步是通过acc_synchnchnchnchnchnchnchnchnchnchnchnchnchnchnchnchnchnchnchnchnchnchnchnchnchnchnchnchnchnchnchnchnchnchnchnchnchnchnchnchnchnchnchnchnchnchnchnchnchnchnchnchnchnchnchnchnchnchnchnchnchnchnchnchnchnchnchnchnchnchnchnchnchnchnchnchnchnchnchnchnchnchnchnchnchnchnchnchnchnchnchnchnchnchnchnchnchnchnchnchnchchnchnchnchnchnchnchnchnchnchnchranization。如果您设置它,则执行线程将首先获得监控,并且可以在成功后执行该方法。
同步锁(本质上是锁的对象),因此在理解原理之前,请引入Java对象。
该对象存储在堆中。每个对象都将包含对象头,实例属性和填充数据(如果是数组对象,则将有一个记录的数组属性)。大小至少为8个字节,因此,如果对象的大小确实可以没有达到这种情况,它将通过填充数据来满足要求。
让我们通过代码来看一下此Java对象
对象的内部结构需要使用JAR包装显示。
可以通过输出结果看出,对象头占据了12个字节,属性为1个字节,总计13个字节,而不是8个字节,因此它将增加3个字节的填充数据。
如果我们将headObject中的字段标志更改为int类型,请查看哪些更改是
可以看出,填充数据已经消失,因为对象头的属性大小为16字节,这正是8个倍数,因此无需执行数据填充。
真正完成锁定对象逻辑的同步锁在对象的头部
通常使用两个属性来存储对象头。主要结构是标记单词和类元数据地址。
对象中对象中对象的对象的哈希码分为年龄和锁定标记。
标记单词存储器存储的内容将随着不同的锁定状态而变化。
在JDK1.6之前,同步锁实现了重量级锁,锁的标识符为10。在其中,指向监视器对象的起始位置(监视器锁)。相关的监视器对象,Monirot被持有通过线程,它被锁定。在Java虚拟机中,Montitor由ObjectMonitor实现。主要数据结构如下图所示:
ObjectMonitor有两个队列,_WAITSET和_ENTRYLIST,用于保存ObjectWaiter对象列表(将每个线程等待锁封装在ObjectWaiter中),_owner指向持有ObjectMonitor对象的线程。线程获取对象的监视器后,输入_owner区域并将监视器的所有者设置为当前线程。在同一Timemonitor上,所有者变量还原为null,计数减1,同时,该线程将进入WaitSet Collection并等待唤醒。如果执行当前线程,它还将释放监视器的值并重置变量以输入获得锁定。
重量级锁的缺点也很明显
从JDK1.6开始,同步增加了一个有偏见且轻巧的锁定,以提高同步的整体性能。
在大多数情况下,不仅锁没有竞争,而且总是通过同一线程获得。因此,为了减少在同一线程中获得锁的成本,引入了偏置锁。
然后继续解释,如何升级到轻质锁?
当锁升级到轻质锁时,如果仍然有新线程可以竞争,首先,此新线程将尝试获取锁,尝试进行一定次(默认的10次)升级到重量级锁。
在这里解释为什么它会在一段时间内变成重量级锁。
一般而言,应快速执行同步代码块中的代码。目前,新的线程旋转很容易在一段时间内获得锁。设置旋转的数量,然后转换为重量级锁。这些竞争线程不必旋转。
同步代码块和同步方法的基础代码
通过这种基本代码,并结合了解释的同步基本原则,它将清楚地理解同步的工作流程。
对于同步方法,这是一种同步方法,可以通过访问访问符号的徽标来区分该方法是否可以区分该方法。当调用该方法时,首先检查访问方法的访问方法徽标。如果设置设置,则需要先获取监视器,然后执行该方法。
同步代码块由MonitorEnter和Monitorexit指令实现。为了确保MonitorEnter和Monitorexit指令仍然可以正确执行异常处理器,当MonitorEnter和MonitoreXIT指令正确配对时。此异常处理器将执行此Monitorexit指令。
如果您认为小鸡蛋很好,就像一波关注一样。让我们一起展示我们对周围社会的坚持。