- 公平锁/非公平锁
-
公平锁 入锁前如果阻塞会自动排队到链表最后面;
public ReentrantLock(boolean fair) { sync = fair ? new FairSync() : new NonfairSync(); }
-
非公平锁 谁先抢到,谁先执行;优势为吞吐量较公平锁大,Synchronized为公平锁;
-
- 可重入锁
-
可重入锁又名递归锁,是指在同一个线程在外层方法获取锁的时候,在进入内层方法会自动获取锁。
-
ReentrantLock 和 Synchronized 是可重入锁
-
Code View
synchronized void setA() throws Exception{ Thread.sleep(1000); setB(); } synchronized void setB() throws Exception{ Thread.sleep(1000); }
-
- 独享锁/共享锁(排它锁)
-
独享锁是指该锁一次只能被一个线程所持有。
ReentrantLock & Synchronized & ReentrantReadWriteLock writeLock().lock()
-
共享锁与独占锁相反,可被多个线程持有。
ReentrantReadWriteLock readLock().lock()
`
-
- 互斥锁/读写锁
- 互斥锁 ReentrantLock
- 乐观锁/悲观锁
- 分段锁
- 对于JDK1.7中
ConcurrentHashMap
采用Segement段锁
- 对于JDK1.7中
- 偏向锁/轻量级锁/重量级锁
-
它们是锁的状态,内存布局分为:对象头、实例数据和对其填充;对象头有可以分为”Mark Word”和类型指针klass。”Mark Word”是关键,默认情况下,其存储对象的HashCode、分代年龄和锁标记位。
-
”Mark Word”的内容:
锁状态 存储内容 标志位 无锁 对象的hashCode、对象分代年龄、是否是偏向锁(0) 01 轻量级 指向栈中锁记录的指针 00 重量级 指向互斥量(重量级锁)的指针 10 GC标记 (空) 11 偏向锁 偏向线程ID、偏向时间戳、对象分代年龄、是否是偏向锁(1) 01 -
整个synchronized锁流程如下: 1. 检测Mark Word里面是不是当前线程的ID,如果是,表示当前线程处于偏向锁 2. 如果不是,则使用CAS将当前线程的ID替换Mard Word,如果成功则表示当前线程获得偏向锁,置偏向标志位1 3. 如果失败,则说明发生竞争,撤销偏向锁,进而升级为轻量级锁。 4. 当前线程使用CAS将对象头的Mark Word替换为锁记录指针,如果成功,当前线程获得锁 5. 如果失败,表示其他线程竞争锁,当前线程便尝试使用自旋来获取锁。 6. 如果自旋成功则依然处于轻量级状态。 7. 如果自旋失败,则升级为重量级锁。
-
- 自旋锁
- 【JDK1.4.2~JDK1.6】之间
-XX:+UseSpinning
开启自旋锁 - 【JDK1.7】后,去掉此参数,由jvm控制;
- 【JDK1.4.2~JDK1.6】之间
锁消除 锁粗化
类锁 对象锁
无锁