- synchronized关键字
- 锁优化
- 自旋锁:通过自旋让线程等待一段时间,不会被立即挂起,看持有锁的线程是否会很快释放锁
- 执行一段无意义的循环实现反复获取锁
- 由来:频繁的阻塞和唤醒线程CPU要从用户态转化为核心态,通常对象锁状态只会持续很短的一段时间,这样做不值得
- 适应性自旋锁:JDK1.6引入,自旋的次数不在固定
- 线程如果自旋成功了,下一次自旋次数会更多
- 如果对于某个锁很少能自旋成功,以后这个锁的自旋次数会减少,以免浪费资源
- 锁消除:JVM检测到不可能存在共享数据竞争,这是JVM会对这些同步锁进行锁消除
- 如使用 StringBuffer、Vector、HashTable 等时会存在隐性加锁操作,JVM检测到这些类的实例变量没有逃逸出非同步的方法,JVM可以将其内部锁消除
- 锁粗化:多个连续的加锁、解锁操作连接在一起,扩展成一个范围更大的锁
- 锁的升级:
- 偏向锁:Java 6之后加入的新锁
- 核心思想:如果一个线程获得了锁,那么锁就进入偏向模式,此时Mark Word 的结构也变为偏向锁结构,当这个线程再次请求锁时,无需再做任何同步操作,即获取锁的过程,这样就省去了大量有关锁申请的操作
- 依据:
- 适用于很少有锁竞争的场合,如果是锁竞争比较激烈的场合,偏向锁就失效了
- 失效后升级成轻量级锁
- 轻量级锁:
- 核心思想:此时Mark Word 的结构也变为轻量级锁的结构
- 依据:对于绝大部分的锁,在整个生命周期内都是不会存在竞争的
- 轻量级锁所适应的场景是线程交替执行同步块的场合,如果存在同一时间访问同一锁的场合,就会导致轻量级锁膨胀为重量级锁
- 获取锁过程:
- JVM在当前线程栈帧中创建锁记录对象,存储锁对象的Mark Word的拷贝以及对象的引用地址
- 将锁对象的对象头中的MarkWord设置成锁记录的地址及锁标志位为00
- 偏向锁:Java 6之后加入的新锁
- 自旋锁:通过自旋让线程等待一段时间,不会被立即挂起,看持有锁的线程是否会很快释放锁
- 锁优化
- ReentrantLock:可重入锁
- 相比于synchonized特点:
- 可中断
- 可以设置超时时间(synchonized会一直等待)
- 可以设置为公平锁(防止线程饥饿)
- 支持多个条件变量
- 相比于synchonized特点:
synchronized和ReentrantLock
最新推荐文章于 2024-04-16 14:44:11 发布
![](https://img-home.csdnimg.cn/images/20240711042549.png)