synchronized和ReentrantLock

本文深入探讨了Java并发优化中的锁机制,包括自旋锁的原理与适应性自旋,锁消除的条件,以及锁粗化、偏向锁、轻量级锁等锁升级过程。同时介绍了ReentrantLock相对于synchronized的特性,如可中断、可设置超时和公平性。这些优化策略旨在提高多线程环境下的性能和效率。
摘要由CSDN通过智能技术生成
  1. synchronized关键字
    1. 锁优化
      1. 自旋锁:通过自旋让线程等待一段时间,不会被立即挂起,看持有锁的线程是否会很快释放锁
        1. 执行一段无意义的循环实现反复获取锁
        2. 由来:频繁的阻塞和唤醒线程CPU要从用户态转化为核心态,通常对象锁状态只会持续很短的一段时间,这样做不值得
      2. 适应性自旋锁:JDK1.6引入,自旋的次数不在固定
        1. 线程如果自旋成功了,下一次自旋次数会更多
        2. 如果对于某个锁很少能自旋成功,以后这个锁的自旋次数会减少,以免浪费资源
      3. 锁消除:JVM检测到不可能存在共享数据竞争,这是JVM会对这些同步锁进行锁消除
        1. 如使用 StringBuffer、Vector、HashTable 等时会存在隐性加锁操作,JVM检测到这些类的实例变量没有逃逸出非同步的方法,JVM可以将其内部锁消除
      4. 锁粗化:多个连续的加锁、解锁操作连接在一起,扩展成一个范围更大的锁
      5. 锁的升级:
        1. 偏向锁:Java 6之后加入的新锁
          1. 核心思想:如果一个线程获得了锁,那么锁就进入偏向模式,此时Mark Word 的结构也变为偏向锁结构,当这个线程再次请求锁时,无需再做任何同步操作,即获取锁的过程,这样就省去了大量有关锁申请的操作
          2. 依据:
          3. 适用于很少有锁竞争的场合,如果是锁竞争比较激烈的场合,偏向锁就失效了
          4. 失效后升级成轻量级锁
        2. 轻量级锁:
          1. 核心思想:此时Mark Word 的结构也变为轻量级锁的结构
          2. 依据:对于绝大部分的锁,在整个生命周期内都是不会存在竞争的
          3. 轻量级锁所适应的场景是线程交替执行同步块的场合,如果存在同一时间访问同一锁的场合,就会导致轻量级锁膨胀为重量级锁
          4. 获取锁过程:
            1. JVM在当前线程栈帧中创建锁记录对象,存储锁对象的Mark Word的拷贝以及对象的引用地址
            2. 将锁对象的对象头中的MarkWord设置成锁记录的地址及锁标志位为00
  2. ReentrantLock:可重入锁
    1. 相比于synchonized特点:
      1. 可中断
      2. 可以设置超时时间(synchonized会一直等待)
      3. 可以设置为公平锁(防止线程饥饿)
      4. 支持多个条件变量
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值