编写目标 阅读前提
使得阅读过本文的读者,对锁的概念不再那么困惑。
对 java,多线程, synchronized 关键字有所认识。
1. 锁概念解释 重要
一段被锁住的代码,在被一个线程执行之前,这个线程需要拿到执行的权限。
这个权限存在于每个对象中,即任何对象都可以做为锁。
但是只有多个线程共享的对象作为锁时,才可以实现线程同步。
2. 乐观锁
乐观锁实现实例: CAS 和 version 控制
3. java 锁升级过程
无锁 ->偏向锁 -> 轻量级锁 -> 重量级锁
4. 各种锁
- 偏向锁
在对象头中保存了 线程id。
- 轻量级锁
使用场景:少量线程交替访问同步代码块
( 自旋获取锁,使得线程处于短时的等待,而避免线程切换的资源消耗。
若获取锁失败过多则升级为重量级锁 )
- 重量级锁
防止 CPU 因自旋而占用资源( 适合大量线程访问 )
- 自旋锁
前来获取锁的线程未能第一时间获取到锁
通过自旋的方式 ( 一段空的 for 循环,或空等待 )
自旋的同时重新尝试获取锁
- 公平锁 非公平锁
多个未获取到锁的线程 按顺序获取锁 即为公平,反之不公平
- 独占锁 共享锁
独占锁:只能一个线程获得锁 ( synchronized,ReentrantLock )
共享锁:多个线程可以获得锁
- 互斥锁 读写锁
分为 读锁 和 写锁,分别互斥,由 JVM 实现
ReentrantReadWriteLock
允许多个线程获取读锁,访问同一资源
只允许一个线程访问资源( 读-读,读-写,写-读,写-写 ),即互斥锁
- 可重入锁
任意线程获取到锁后,能够再次获取而不会被阻塞,可以避免死锁
ReentrantLock 和 synchronized
释放锁时也需按重入次数依次释放
- 分段锁
ConcurrentHashMap 为例:内部分为多个 HashMap
计算 key 的 hashcode 之后,得知 所处的数据段,只对该段加锁
如有建议请评论或私信.