一.锁的底层实现
线程的同步是Monitor对象实现。由方法调用指令读取常量池中的方法ACC_SYNCHRONIZED标志来隐式实现。
【Java 虚拟机中的同步(Synchronization)基于进入和退出管程(Monitor)对象实现。
同步方法 并不是由 monitor enter 和 monitor exit 指令来实现同步的,
而是由方法调用指令读取运行时常量池中方法的ACC_SYNCHRONIZED 标志来隐式实现的】
线程对象内存简图:
_WaitSet是用于管理等待队列(wait)线程的
_EntryList是用于管理锁池阻塞线程的
_Owner标记用于记录当前执行线程
线程底层运行原理图:
二.锁的种类
Java中锁的种类大致分为偏向锁,自旋锁,轻量级锁,重量级锁。
锁的使用方式为:
先提供偏向锁,如果不满足的时候,升级为轻量级锁,再不满足,升级为重量级锁。
自旋锁是一个过渡的锁状态,不是一种实际的锁类型。
锁只能升级,不能降级。
①偏向锁
是一种编译解释锁。
没有多线程并发争抢同一个锁。
ACC_SYNCHRONIZED变量使用的时候表示偏向锁锁定。
②轻量级锁
多线程并发争抢同一个锁,升级为轻量级锁。
使用标记ACC_SYNCHRONIZED标记记录的获取到锁线程。
ACC_UNSYNCHRONIZED标记记录未获取到锁信息的线程。
只两个线程争抢锁标记的时候,优先使用轻量级锁。
两个线程也可能出现重量级锁。
③自旋锁
当获取锁的过程中,未获取到。
为了提高效率,JVM自动执行若干次空循环,再次申请锁,而不是进入阻塞状态的情况。