Java 中什么是公平锁和非公平锁?

· 约 2 分钟读完 · 第 98 / 274 章

推荐答案

在Java中,公平锁和非公平锁是两种不同的锁获取策略。公平锁是指多个线程按照申请锁的顺序来获取锁,而非公平锁则允许线程“插队”,即新请求锁的线程有可能在等待队列中的线程之前获取锁。

公平锁

  • 定义:公平锁保证等待时间最长的线程优先获取锁。
  • 实现:在Java中,ReentrantLock类可以通过构造函数参数设置为公平锁。
  • 优点:公平锁可以避免线程饥饿问题,确保所有线程都有机会执行。
  • 缺点:公平锁的性能通常低于非公平锁,因为它需要维护一个有序的等待队列。

非公平锁

  • 定义:非公平锁不保证线程获取锁的顺序,新请求锁的线程有可能在等待队列中的线程之前获取锁。
  • 实现:ReentrantLock类的默认实现是非公平锁。
  • 优点:非公平锁的性能通常高于公平锁,因为它减少了线程切换的开销。
  • 缺点:非公平锁可能导致线程饥饿问题,某些线程可能长时间无法获取锁。

本题详细解读

公平锁的实现

在Java中,公平锁的实现通常依赖于一个有序的等待队列。当一个线程请求锁时,如果锁已经被其他线程持有,该线程会被放入等待队列的末尾。当锁被释放时,等待队列中的第一个线程(即等待时间最长的线程)将获得锁。

非公平锁的实现

非公平锁的实现则允许新请求锁的线程“插队”。当一个线程请求锁时,如果锁当前没有被其他线程持有,该线程可以直接获取锁,而不需要进入等待队列。即使锁被其他线程持有,新请求锁的线程也有可能在某些情况下直接获取锁,而不需要等待队列中的线程。

性能比较

  • 公平锁:由于需要维护一个有序的等待队列,公平锁的性能通常较低。在高并发场景下,公平锁可能会导致较多的线程切换和上下文切换,从而影响整体性能。
  • 非公平锁:非公平锁的性能通常较高,因为它减少了线程切换的开销。然而,非公平锁可能导致某些线程长时间无法获取锁,从而引发线程饥饿问题。

使用场景

  • 公平锁:适用于需要严格保证线程执行顺序的场景,例如某些需要顺序处理的业务逻辑。
  • 非公平锁:适用于对性能要求较高的场景,且线程饥饿问题不会对业务逻辑产生重大影响的情况。

通过理解公平锁和非公平锁的区别及其适用场景,开发者可以根据具体需求选择合适的锁策略,以优化程序的性能和可靠性。