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
相关文章
相关标签/搜索