java如何实现锁
Java 锁的实现方式
Java 提供了多种锁机制,用于控制多线程对共享资源的访问。以下是常见的锁实现方式:
synchronized 关键字
synchronized 是 Java 中最基本的锁机制,可以用于方法或代码块。它基于对象监视器(monitor)实现,确保同一时间只有一个线程可以执行被锁定的代码。
方法锁示例:
public synchronized void method() {
// 临界区代码
}
代码块锁示例:
public void method() {
synchronized(this) {
// 临界区代码
}
}
ReentrantLock
ReentrantLock 是 java.util.concurrent.locks 包中的一个可重入锁实现,提供了比 synchronized 更灵活的锁操作。
基本用法:
private final ReentrantLock lock = new ReentrantLock();
public void method() {
lock.lock();
try {
// 临界区代码
} finally {
lock.unlock();
}
}
公平锁与非公平锁:
// 非公平锁(默认)
ReentrantLock nonFairLock = new ReentrantLock();
// 公平锁
ReentrantLock fairLock = new ReentrantLock(true);
ReadWriteLock
ReadWriteLock 接口及其实现 ReentrantReadWriteLock 提供了读写分离的锁机制,允许多个读操作同时进行,但写操作独占。
示例:
private final ReadWriteLock rwLock = new ReentrantReadWriteLock();
public void readMethod() {
rwLock.readLock().lock();
try {
// 读操作
} finally {
rwLock.readLock().unlock();
}
}
public void writeMethod() {
rwLock.writeLock().lock();
try {
// 写操作
} finally {
rwLock.writeLock().unlock();
}
}
StampedLock
StampedLock 是 Java 8 引入的一种新的锁机制,提供了乐观读锁、悲观读锁和写锁三种模式。
示例:
private final StampedLock sl = new StampedLock();
// 写锁
public void writeMethod() {
long stamp = sl.writeLock();
try {
// 写操作
} finally {
sl.unlockWrite(stamp);
}
}
// 悲观读锁
public void readMethod() {
long stamp = sl.readLock();
try {
// 读操作
} finally {
sl.unlockRead(stamp);
}
}
// 乐观读锁
public void optimisticRead() {
long stamp = sl.tryOptimisticRead();
// 读操作
if (!sl.validate(stamp)) {
stamp = sl.readLock();
try {
// 重新读操作
} finally {
sl.unlockRead(stamp);
}
}
}
Condition 对象
Condition 接口提供了类似 Object.wait() 和 Object.notify() 的功能,但更灵活,可以与 ReentrantLock 配合使用。
示例:
private final ReentrantLock lock = new ReentrantLock();
private final Condition condition = lock.newCondition();
public void awaitMethod() throws InterruptedException {
lock.lock();
try {
condition.await();
} finally {
lock.unlock();
}
}
public void signalMethod() {
lock.lock();
try {
condition.signal();
} finally {
lock.unlock();
}
}
原子类
java.util.concurrent.atomic 包提供了一系列原子类,如 AtomicInteger、AtomicLong 等,它们使用 CAS(Compare-And-Swap)操作实现无锁线程安全。
示例:
private final AtomicInteger counter = new AtomicInteger(0);
public void increment() {
counter.incrementAndGet();
}
锁的选择建议
- 简单场景:使用
synchronized关键字 - 需要更灵活的控制:使用
ReentrantLock - 读写分离场景:使用
ReadWriteLock - 高性能读多写少场景:考虑
StampedLock - 简单计数器场景:使用原子类







