一、互斥锁
1、锁的可重入性
“可重入锁”是指当一个线程调用 object.lock()获取到锁,进入临界区后,再次调用object.lock(),仍 然可以获取到该锁。显然,通常的锁都要设计成可重入的,否则就会发生死锁。
synchronized关键字,就是可重入锁。
2、类继承层次
Concurrent 包中的与互斥锁(ReentrantLock)相关类之 间的继承层次,如下图所示:
3、锁的公平性vs.非公平性
什么叫公平锁和非公平锁呢?先举个现实生活中的例子,一个人去火车站售票窗口买票,发现现场 有人排队,于是他排在队伍末尾,遵循先到者优先服务的规则,这叫公平;如果他去了不排队,直接冲 到窗口买票,这叫作不公平。
对应到锁的例子,一个新的线程来了之后,看到有很多线程在排队,自己排到队伍末尾,这叫公 平;线程来了之后直接去抢锁,这叫作不公平。默认设置的是非公平锁,其实是为了提高效率,减少线 程切换。
锁实现的基本原理
Sync的父类AbstractQueuedSynchronizer经常被称作队列同步器(AQS),这个类非常重要,该 类的父类是AbstractOwnableSynchronizer。 此处的锁具备synchronized功能,即可以阻塞一个线程。
为了实现一把具有阻塞或唤醒功能的锁, 需要几个核心要素:
1. 需要一个state变量,标记该锁的状态。state变量至少有两个值:0、1。对state变量的操作, 使用CAS保证线程安全。
2. 需要记录当前是哪个线程持有锁。
3. 需要底层支持对一个线程进行阻塞或唤醒操作。
4. 需要有一个队列维护所有阻塞的线程。这个队列也必须是线程安全的无锁队列,也需要使用 CAS。