java 如何加锁
加锁的基本概念
在Java中,加锁是一种同步机制,用于控制多线程对共享资源的访问。通过加锁,可以确保同一时间只有一个线程能够访问临界区代码或资源,从而避免数据竞争和不一致性问题。
synchronized 关键字
synchronized是Java中最基本的加锁机制,可以用于方法或代码块。使用synchronized修饰的方法或代码块在同一时间只能被一个线程访问。
// 同步方法
public synchronized void synchronizedMethod() {
// 临界区代码
}
// 同步代码块
public void someMethod() {
synchronized (this) {
// 临界区代码
}
}
ReentrantLock 类
ReentrantLock是java.util.concurrent.locks包中的一个锁实现,提供了比synchronized更灵活的加锁机制。它支持公平锁和非公平锁,并提供了尝试获取锁、超时获取锁等功能。
import java.util.concurrent.locks.ReentrantLock;
private final ReentrantLock lock = new ReentrantLock();
public void someMethod() {
lock.lock();
try {
// 临界区代码
} finally {
lock.unlock();
}
}
ReadWriteLock 接口
ReadWriteLock接口提供了读写锁机制,允许多个线程同时读取共享资源,但在写入时独占资源。ReentrantReadWriteLock是其实现类。
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.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引入的一种新的锁机制,提供了乐观读锁、悲观读锁和写锁三种模式。它在高并发读场景下性能优于ReadWriteLock。

import java.util.concurrent.locks.StampedLock;
private final StampedLock stampedLock = new StampedLock();
public void optimisticRead() {
long stamp = stampedLock.tryOptimisticRead();
// 读取共享资源
if (!stampedLock.validate(stamp)) {
stamp = stampedLock.readLock();
try {
// 重新读取共享资源
} finally {
stampedLock.unlockRead(stamp);
}
}
}
public void writeMethod() {
long stamp = stampedLock.writeLock();
try {
// 写入共享资源
} finally {
stampedLock.unlockWrite(stamp);
}
}
锁的最佳实践
在使用锁时,需要注意避免死锁、锁竞争和性能问题。尽量减少锁的持有时间,避免在锁内执行耗时操作。优先使用更高级的并发工具类(如ConcurrentHashMap、CountDownLatch等)以减少显式加锁的需求。






