Java的ReentrantLock
是一个高级的线程同步工具,提供了比传统的synchronized
方法和语句更灵活、更丰富的线程同步机制。这个锁属于可重入锁(也称为递归锁),意味着同一个线程可以多次获取同一个锁而不会产生死锁。下面详细解释和说明ReentrantLock
的特性和用法:
ReentrantLock
实例时可以选择是公平锁还是非公平锁,默认是非公平锁。lock()
方法获取锁。如果锁已被其他线程持有,则当前线程会等待。unlock()
方法释放锁。每个lock()
调用都需要配对的unlock()
调用。ReentrantLock
提供了一种能力,使得线程能够响应中断。当在锁等待过程中,线程可以选择放弃等待并继续执行。ReentrantLock
提供了条件变量(Condition)功能,允许线程在某些条件不满足时挂起,直到条件改变时再继续执行。synchronized
的比较synchronized
是Java内置的同步机制,更简单,但功能也较少。ReentrantLock
提供更高的灵活性,比如可中断的锁等待、公平锁选择、多个条件变量等。import java.util.concurrent.locks.ReentrantLock;
public class Example {
private final ReentrantLock lock = new ReentrantLock();
public void method() {
lock.lock(); // 获取锁
try {
// 临界区代码
} finally {
lock.unlock(); // 释放锁
}
}
}
在使用ReentrantLock
时,最佳实践是始终在try
/finally
块中释放锁,以确保即使在临界区代码中发生异常时,锁也会被释放。通过这种方式,ReentrantLock
提供了比synchronized
更精细和更灵活的线程同步控制。
ReentrantLock
的非公平锁实现主要基于几个核心概念和机制,这些机制和概念使得ReentrantLock
在处理非公平锁时表现出高效和灵活性。下面是ReentrantLock
非公平锁实现的关键方面:
ReentrantLock
使用一个内部的变量(通常是一个volatile
字段)来维护锁的状态,这个状态指示锁是否被某个线程持有。ReentrantLock
使用CAS操作来尝试获取锁。CAS是一种原子操作,用于更新锁的状态,如果当前状态是未锁定的,则将其设置为锁定状态。ReentrantLock
的非公平锁实现通过允许线程直接尝试获取锁,而不是按照等待队列中的顺序,从而实现非公平性。这种方法优化了性能,但也可能导致线程饥饿的问题。在设计并发控制时,选择使用公平锁还是非公平锁取决于特定应用的需求和性能考量。
是的,在不存在新线程争抢的情况下,非公平锁中已加入等待队列的线程通常会按照FIFO(先进先出)原则获取锁。这意味着,尽管非公平锁允许新到达的线程有机会在加入等待队列之前获取锁,但一旦线程进入了等待队列,它们通常会按照它们加入队列的顺序来获取锁。
锁争抢:在锁被释放时,如果有新的线程尝试获取锁,这个线程可以直接尝试获取锁,而不需要加入等待队列。
等待队列:如果直接获取锁失败,线程将加入等待队列。一旦线程处于等待队列中,它将等待锁按照队列的顺序释放给前面的线程。
按顺序获取:在没有新线程争抢的情况下,当锁被释放时,通常是等待队列中的第一个线程(即最长时间等待的线程)获得机会来获取锁。
在没有新线程竞争的情况下,非公平锁的行为类似于公平锁,即遵循FIFO原则,按照线程加入等待队列的顺序来获取锁。然而,非公平锁的关键区别在于它提供了新到达线程直接尝试获取锁的机会,这可能在某些情况下导致等待队列中的线程被“插队”。
synchronized
有什么区别?ReentrantLock
的非公平锁和Java的synchronized
关键字在多个方面有着显著的区别。这些区别涵盖了锁的行为、灵活性、功能和性能等多个方面。
synchronized
: 不保证任何关于线程获取锁的顺序。虽然它也是非公平的,但在具体实现中,它可能表现出某种隐性的公平性或随机性。或者说ReentrantLock
的非公平锁相对于synchronized
会更不公平。tryLock
)、可以响应中断、支持条件变量(Condition
)等。synchronized
: 相对简单,没有提供上述高级特性。它是自动管理锁的,即在进入和退出同步块时自动获取和释放锁。synchronized
: 只与单一的条件队列相关联,即每个对象的内置锁关联一个条件队列。synchronized
: 近年来,Java虚拟机对synchronized
做了大量优化(如偏向锁和轻量级锁),使得其性能显著提高,尤其是在低竞争环境下。finally
块中。synchronized
: 更易于使用,因为进入和退出同步块时锁的获取和释放是自动的。尽管ReentrantLock
的非公平锁和synchronized
都不保证公平性,但ReentrantLock
提供了更多的功能和灵活性。它允许更精细的锁控制,包括响应中断、尝试锁定、支持多个条件变量等。然而,这些额外的功能也使得ReentrantLock
的使用比synchronized
更复杂。