Java多线程同步关键词是经常使用的多线程同步手段。它能够修饰静态类方法,实例方法,或代码块。修饰static静态方法时是对整个类加锁。java
1、实现原理多线程
在JVM中对象内存分三块区域,对象头、实例数据、对齐填充数据。Java对象头是实现synchronize锁对象的基础,它使用的锁对象就是存储在Java对象头里。JVM中用2个字节存储对象头,主要结构是由Mark Word和Class Metadata Address 组成,前者MarkWord里存储对象的hashcode、锁信息、分代年龄、GC标志等信息,后者存放类型指针,指向对象的类元数据。并发
从字节码可知synchronized代码块的实现用的是mmonitorenter和monitorexit指令,synchronized方法同步是隐式同步,JVM从方法常量池中的方法表结构中的ACC_SYNCHRONIZED访问标志区分一个方法是不是同步方法。app
2、JVM锁优化优化
JAVA6后JVM对同步关键词进行优化,引入偏向锁、自旋锁、轻量级锁等概念。对象头中锁状态有无锁状态、偏向锁、轻量级锁和重量级锁。操作系统
JVM在JIT编译时经过上下文扫描,会去除不可能存在共享资源竞争的锁,减小不必的请求锁时间,好比方法内StringBuffer对象调用append时,JVM会自动将其消除。.net
JAVA6 默认引入了偏向锁,若是一个线程获取了锁,则锁就进入偏向模式,此时Mark Word的结构也从无锁状态变为偏向锁结构,当这个线程再请求锁时无需作申请锁等相关操做。若是每次申请锁的线程都不相同则不该该用偏向锁。线程
偏向锁失败后会先升级为轻量级锁,此时对象头Mark Word结构变为轻量级锁结构,适应线程交替执行同步块的场合,轻量级锁使用的依据是“对大部分锁,在整个同步周期内都不存在竞争”。若是存在同一时间访问同一锁的状况,轻量级锁就会失败。指针
轻量级锁失败后虚拟机为了不线程真实的在操做系统层面挂起,会进行自旋锁优化手段。它基于大多数状况下线程持有锁的时间都不会太长,JVM让想要获取锁的线程作一下子空循环若是获得锁就进入临界区,若是失败就在操做层面挂起,升级为重量级锁。code