synchronized通过对象内部的一个叫做监视器锁的东西来实现的。

监视器锁本身依赖于操作系统底层的互斥锁Mutex Lock来实现的,同步代码块是通过monitorentermoniterexit 指令来获取线程的执行权。同步方法是通过加ACC_SYNCHONIZED 标识获取线程的执行权。

操作系统实现线程之间的切换需要从用户态转换到核心态,成本很高,状态转换要花费比较长的时间。

这就是synchronized效率低的原因。这种依赖于操作系统MutexLock实现的锁成为重量级锁

synchronized v.s. volatile

Volatile:内存可见(不保证原子性,不保证互斥性);防止CPU指令重排(内存屏障)

扩展:

如何保证内存可见?

JMM通过控制主内存与每个线程的本地内存之间的交互,来为Java程序员提供内存可见性保证。

什么是内存屏障?

MM属于语言级的内存模型,它确保在不同的编译器和不同的处理器平台之上,通过禁止特定类型的编译器重排序和处理器重排序,为程序员提供一致的内存可见性保证

happens-before规则

happens-before表示的是前一个操作的结果对于后续操作是可见的,它是一种表达多个线程之间对于内存的可见性。所以我们可以认为在 JMM 中,如果一个操作执行的结果需要对另一个操作可见,那么这两个操作必须要存在happens-before关系。这两个操作可以是同一个线程,也可以是不同的线程。