Skip to content

Java 中的各种锁的概念

  • 悲观锁和乐观锁
    • 乐观锁
      • 假定当前环境是一种读多写少的环境,读取数据时不会遇到其他线程修改数据,遇到并发的概率是很低的.所以通过CAS方式对数据进行标注.读共享,写阻塞
    • 悲观锁
      • 和乐观锁的思想相反,假定当前环境是一种写多读少,读取数据时,一定会有其他线程修改了数据.所以写数据时首先会先上锁,只能有一个线程进行读操作或写操作.
  • 自旋锁,可重入锁,读写锁
    • 自旋锁
      • 当一个线程独占锁之后,其他线程在拿不到锁的情况,自旋操作,直到获取到锁.
      • 自旋锁避免了系统级的挂起和恢复
      • 如果锁的时间比较长,自旋也是浪费资源
    • 可重入锁
      • 一种可以允许多个线程进入的锁,如synchronized和ReentrantLook
      • 要注意加锁和释放锁,否则会导致锁对不匹配
    • 读写锁
      • 读锁分离,读的时候判断读锁,写的时候判断写锁
      • 同类型不互斥,不同类型互斥
  • 公平锁和非公平锁
    • 公平锁
      • 获取锁之前必须先进到队列排队
    • 非公平锁
      • 先尝试获取锁,获取不到则进入队列排队
      • 最后进来的线程很容易拿到锁,效率比公平锁高
      • 并发突起的时候容易导致队列中一直没有机会
  • 轻量级锁和重量级锁
    • 重量级锁
      • 通过监视器锁(monitor)来实现,依赖操作系统的锁机制
      • Sychronized包含有重量级锁
    • 轻量级锁
      • 无竞争情况下使用CAS操作消除同步使用的互斥量
      • 如果存在竞争,除了互斥量本身的开销,还额外产生CAS开销,有竞争的情况下,轻量级锁比重量级锁更慢
  • 偏向锁
    • 这个锁会偏向于第一个获得它的线程
    • 不需要CAS操作
    • 如果程序中大多数锁都总被多个不同的线程访问,偏向锁会显得比较多余
  • 分段锁
    • 对数据结构进行分段,不同的分段使用不同的锁
  • 其他锁
    • 共享锁
    • 互斥锁,同步锁,悲观锁,独占锁同义
  • 死锁
    • 一种线程互斥并等待资源现象
      • 线程A持有资源x,需要获取资源y
      • 线程B持有资源y,需要获取资源x
      • 两个线程都不释放自己持有的资源