JAVA面试——JAVA主流锁

  • 乐观锁&悲观锁
    • 悲观锁:获取数据时加锁,(synchronized关键字、Lock实现类)
    • 乐观锁:使用数据时不加锁,更新时判断之前是否有其他线程更新数据,(CAS算法)
      • CAS(Compare And Swap):
        • 无锁算法,实现线程的变量同步
        • java.util.concurrent包中的原子类
        • 实现方法:
          • 需要读写的内存值V
          • 进行比较的A
          • 要写入的新值B
        • 存在的问题:
          • ABA问题
          • 循环时间长、开销大
          • 只能保证对一个共享变量的原子操作
  • 自旋锁&适应性自旋锁
    • 自旋锁:
      • 同步资源锁定时间短,避免线程切换导致的开销,让后面请求锁的线程等待而进行自旋
      • 缺点:浪费处理器资源
    • 适应性自旋锁:
      • 自旋时间不固定,根据同一个锁上一次的等待时间和锁拥有者运行状态决定
      • 自旋很少成功,则阻塞线程
  • 无锁&偏向锁&轻量级锁&重量级锁
    • 针对synchronized的锁状态
    • 重量级锁:依赖操作系统的Mutex Lock(互斥锁)
    • 偏向锁:一段同步代码一直被一个线程所访问,不存在线程竞争,自动获取锁,不通过CAS加解锁
    • 轻量级锁:当锁是偏向锁时,被其他线程访问时变成轻量级锁,通过自旋的方式获取锁,不会阻塞
    • 总结:偏向锁通过对比Mark Word解决加锁问题,避免CAS操作;轻量级锁通过CAS操作和自旋解决加锁问题,避免线程阻塞;重量级锁将其他线程阻塞
  • 公平锁&非公平锁
    • 公平锁:按照申请锁的顺序排队获取锁,不会饿死,吞吐效率低
    • 非公平锁:获取锁时获取不到排队,可用直接获取,排队线程可能饿死
  • 可重入锁&非可重入锁
    • 可重入锁:
      • 同一个线程外层方法获取锁后,内层方法自动获取锁(ReentrantLock、synchronized)
    • 非可重入锁:
      • 重复调用同步资源时会死锁
  • 独享锁&共享锁
    • 独享锁(互斥锁、排他锁)
      • 对数据A加锁后,其他线程不能对A加其他类型的锁,锁一次只能被一个线程持有
      • synchronized、ReentrantLock
    • 共享锁
      • 可以被多个线程持有,多个线程可以同时对A加共享锁,共享锁只读不写
      • ReentrantReadWriteLock
posted @ 2019-02-21 22:40  李怕怕  阅读(449)  评论(0编辑  收藏  举报