https://www.nowcoder.com/discuss/353158151543398400?sourceSSR=search

三个线程会按照请求锁的顺序依次获取锁并执行任务,释放锁后下一个排队的线程获取锁。

在 Java 的 ReentrantLock 中,线程是如何排队的取决于锁的公平性设置。如果公平性设置为 true,则锁是公平的,否则是非公平的。

公平锁

公平锁 (fair lock) 是按照线程请求锁的顺序来分配锁的。也就是说,先请求锁的线程会先获得锁,后请求锁的线程会后获得锁。这种机制是通过一个先进先出(FIFO)队列来实现的。

在公平锁的情况下,当多个线程竞争同一个 ReentrantLock 时,线程进入锁的顺序如下:

  1. 线程 A 试图获取锁,发现锁当前被持有,则线程 A 进入等待队列。
  2. 线程 B 试图获取锁,也发现锁被持有,则线程 B 也进入等待队列,排在线程 A 后面。
  3. 线程 C 试图获取锁,同样发现锁被持有,则线程 C 进入等待队列,排在线程 B 后面。

当锁释放时,等待队列中的第一个线程(线程 A)会被唤醒并获得锁,随后是线程 B,然后是线程 C。

非公平锁

非公平锁 (non-fair lock) 则没有这种顺序保证,线程可以插队。非公平锁可能会使得某些线程比其他线程更快地获取锁,尽管它们可能稍后请求锁。

在非公平锁的情况下,线程进入锁的顺序如下:

  1. 线程 A 试图获取锁,发现锁当前被持有,则线程 A 进入等待队列。
  2. 线程 B 试图获取锁,也发现锁被持有,则线程 B 也进入等待队列,排在线程 A 后面。
  3. 线程 C 试图获取锁,同样发现锁被持有,则线程 C 进入等待队列,排在线程 B 后面。