编译后,Java代码将成为Java字节码。字节码通过类型加载器加载到JVM中。JVM执行字节代码。最后,JVM和指定的CPU的实施。
在同时编程中,同步和挥发性关键字起着重要作用。挥发性是一种轻巧的同步,可确保在多处理器开发中共享变量的“可见性”。可见的含义是,当一个线程修改一个共享变量时,另一个线程可以读取此修改后值的值。如果正确使用了挥发性关键字,则将低于同步成本,因为它不会导致上下文竞争不超出上下文编排和调度
内存屏障中的内存屏障是一组处理器指令,以实现可以按内存操作顺序分配的最小单元。处理器在填充缓存线时将加载整个高速缓存线。现代CPU需要执行数百个CPU指令原子操作原子操作。该数字是缓存。处理器将整个缓存线读取到适当的缓存(L1 L2 L3)缓存缓存缓存命中。如果高速缓存填充操作的内存位置仍然是访问处理器的地址,则处理器将从高速缓存中的缓存中从缓存中的缓存中从缓存中进行。阅读操作号而不是内存hit Write命中。当处理器将操作号码关联放在存储器缓存区域时,他将首先检查缓存内存地址是否在缓存中。如果有有效的缓存,则处理器将将此操作写回缓存,而不是写回存储器。此操作是写下缺乏令状会错过缓存。有效的缓存线写入了不存在的内存区域原理:通过JVM生成的最终组装说明,挥发修改变量将具有额外的编译代码线。这条代码是锁定前缀。
锁定前缀的指示将在多核处理器下引起两件事
为了提高处理速度,处理器不会直接与内存通信。相反,系统内存中的数据首先读取系统内存中的内存缓存(L1 L2或其他),但是它不知道操作后何时写内存。如果表达了挥发性变量,JVM将发送一个将前缀指令锁定到处理器,并写入变量位于系统内存的缓存线的数据。值,计算操作将存在问题。因此,在多处理器下,为了确保每个处理器的缓存是一致的,将实现缓存一致性协议。每个处理器都可以通过嗅探在总线上传播的数据来检查您的缓存是否到期。当设备发现与其缓存数据相对应的数据的内存地址已修改时,当前处理器的缓存线将设置为无效。当处理器修改此数据时,它将从内存到缓存的数据读取数据。
同步在多线程并发编程中一直是退伍军人角色,许多人称其为重量级。轻巧的锁以及锁的存储结构和升级过程。
在Java中以三种表达形式同步
当线程试图访问同步代码块时,它必须首先获得锁,退出或投掷异常,并且必须释放锁。名称锁定的位置存在?锁定在锁中存储了哪些信息?
在JVM规范中,您可以看到JVM中同步的实现原理。JVM基于输入和退出监视对象以实现方法同步和代码块同步。两者的详细信息是不同的。代码块是使用MonitorEnter和Monitorexit指令实现的,并且该方法在同一情况下同时使用。这在JVM规范中没有解释。但是,这两个说明也可以实现方法。
Java对象中存在同步使用的锁。如果对象是数组类型,则虚拟机使用3个单词宽度(Word)来存储对象头。如果对象是非数据类型,则虚拟机使用2个单词来存储对象头。1in 32-bit虚拟机宽度等于4个字节,即32位。
Java对象头的长度
32/64bitmark Word存储对象hashcod或锁定信息32/64BitClass元数据地址,以存储对象类型数据的对象类型数据的长度32/64BitArray长度(如果当前对象是阵列为阵列)标记Word的default hashCodeDifferentifEdifferentifedifferentifediftifferentifediftiffirentifeditial年龄和锁定雄心勃勃。
Java对象头存储结构
带有锁定状态对象的HashCode对象的不同年龄001,在操作周期内,存储在Mark Word中的数据将随着锁定位置的更改而变化。内容更为复杂。如果您有兴趣,可以查看相关书籍。
为了减少获得锁和释放锁的性能消耗,Java SE 1.6引入了“偏置锁”和“轻量级锁”。在Java SE 1.6中,锁中有四个州。水平从低到高:没有锁定状态,锁定状态,轻量级锁定状态和重量级锁状态,这些状态将随着比赛的逐渐升级。注意:锁的升级是不可逆的,这意味着偏置锁定为升级到轻质锁,不能降级到有偏的锁。
2.1.1作者对锁热点研究的研究发现,在大多数情况下,锁不仅没有多线程竞争,而且通过同一线程获得了很多次。ESSENCENOTE:ESSENCENOTE:这是设计的原因和解决方案偏置锁
2.1.1.1当线程访问同步代码块并获取锁时,锁定锁时,锁定锁定的锁定锁定线的锁定偏置的线程ID和堆栈框架将无需执行CAS操作以执行CAS操作锁定。它只需要仅测试当前线程的偏置锁是否存储在线头标记字中。如果测试成功,则意味着该线程已锁定。如果测试失败,则需要测试是否锁定标记单词中的徽标设置为设置为设置(指示当前的偏差锁定):如果没有设置,请使用CAS竞争锁;偏置锁定的锁定指示当前线程。
2.1.1.2偏置锁的取消(在这里非常出色)使用锁释放锁的机制用于锁定。因此,当其他线程尝试竞争偏置锁定时,持有偏置锁的线程将释放有偏见的锁。锁定的撤回需要等待全局安全点(此时在此时间点执行字节代码)它首先将用偏置锁悬挂线,然后检查持有锁的线是否还活着。如果线程不在活动中,请将对象头设置为锁定状态;如果线程还活着,则具有偏置锁的堆栈将受到影响。执行,遍历目标的锁定记录,堆栈中的锁记录和对象头的标记单词,要么是偏向其他线程,或锁定标记还活着。该物体不适合作为偏置锁。
2.1.1.3关闭偏置锁定Java 1.6 1.7默认情况下打开偏置锁,但是在应用程序启动几秒钟后不会激活它。我们可以修改JVM参数,这一切都没有竞争,并且可以直接关闭偏置锁
2.1.2轻质锁2.1.2.1轻型锁加线程在执行同步代码块之前,JVM将创建一个用于将锁定记录存储在当前线程堆栈帧中的空间,并将目标标头复制在目标标头中以复制标记字,以在标题头。在锁定记录中,该官员称为位移标记单词。然后线程尝试使用CAS将对象头中的标记字替换为锁定记录的指针。如果成功,当前线程是锁定的;如果失败,则意味着其他线程竞争锁定,当前线程将尝试获取锁。
2.1.2.2轻质锁解解锁轻量锁,使用CAS操作将流离失所的标记单词替换为对象头,如果成功,则意味着没有竞争;如果失败了,则意味着当前锁中存在竞争,锁将扩展到锁的扩展,成为锁的扩展。轻量级锁。注意:因为旋转过程会消耗CPU,因此为了避免无用的旋转,一旦将其升级到重量级锁,它就不会返回轻质锁定状态。当当前锁定在重量级锁中时,其他线程会尝试锁定锁,这将被阻止。当释放锁定锁的线程时,将唤醒这些线程,并重新锁定锁。
2.1.3锁比较锁和缺点比较的优点和缺点
锁锁和解锁过程没有其他消费。与非同步方法相比,只有纳米级别的差异。如果线程在锁定竞赛中,它将带来额外的锁定锁定费用。轻型锁竞赛的线程不会被阻止,从而提高了程序的响应速度。如果未进入锁定竞赛的线程将始终消耗CPU来追求响应时间。SSPIN,没有CPU线程阻止,可以在响应时间内缓慢追求吞吐量,则可以实现同步块中的长期执行速度在Java中,通过锁定和循环CAS来实现原子操作。
JVM中的CAS操作使用处理器提供的CMPXCHG指令。自助CAS的基本思想是循环CAS操作,以了解其成功,并且示例代码实现了安全的计数器和非Seccure计数器。
从JDK 1.5开始,JDK填充了一些类支持的原子操作,例如Atomicboolean,Atomicinteger,Atomiclong,对应于不同类型的原子操作。这些类提供了非常有用的工具方法,例如原子的自我调查和自我还原。
3.1.1 CAS实施实施原子操作的三个主要问题锁定机制,可确保只有锁定的线可以操作锁定存储器区域。JVM内部有许多锁,偏向锁,轻量级锁和重量级锁定。除了有偏置的锁外,JVM实现方法还使用循环CAS机制,也就是说,当线程想要输入同步代码块时,请使用循环CAS获得锁定。当它退出同步代码块时
参考