java 提供两种锁 volatile 和 synchronized
volatile 轻量级锁,锁缓存,当数据变更写入到主内存,通知其他cup所持有的数据失效,从主内存中重新读取
synchronized 重量级锁。锁对象或者类class. 锁存状态放在监视器对象的头部。
1.锁普通方法,锁的是当前实例对象。同一个实例对象多线程调用被锁的方法只能有一个执行,另外一个等待锁的释放。不同对象可以执行同一个被锁的方法。因为监视器是对象的实例。
2.锁静态方法,锁的是类class. 不同实例或者同一实例都要等持有锁的对象执行完毕之后才能下个执行。因为监视器是类。
3.锁代码块。若锁的是对象实例则和1一样。若锁的是类则和2一样。
锁的四种状态
无锁
偏向锁:
大多数情况下不存在锁的竞争,甚至经常被同一线程获取锁。为了让线程以更低的代价加入锁,引入皮偏向锁。
偏向锁是在监视器的头部存放一个偏向锁的状态。先判断是否存在偏向锁状态,若存在则执行,否则使用CAS去竞争锁。
轻量级锁:
访问同步代码块之前,先复制监视器中的mark work(锁头信息),线程尝试使用CAS替换监视器锁记录的指针,若成功则指向当前线程,开始执行。若失败则表示其他线程竞争到锁。此线程尝试使用自旋获取锁。
轻量级锁解锁时,使用CAS替换回对象头,失败表示当前锁存在竞争,则膨胀成重量级锁
重量级锁