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