在Java中,加锁的方式主要有以下几种:
1. synchronized 关键字
synchronized 是Java中最基本的加锁机制,可以用于方法或代码块。
实例方法:
public synchronized void method() {
// 同步代码
}
锁的是当前实例对象。
静态方法:
public static synchronized void staticMethod() {
// 同步代码
}
锁的是当前类的 Class 对象。
代码块:
public void method() {
synchronized (this) {
// 同步代码
}
}
锁的是指定对象。
2. ReentrantLock
ReentrantLock 是 java.util.concurrent.locks 包中的类,提供了比 synchronized 更灵活的锁机制。
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Example {
private final Lock lock = new ReentrantLock();
public void method() {
lock.lock(); // 加锁
try {
// 同步代码
} finally {
lock.unlock(); // 释放锁
}
}
}
3. ReadWriteLock
ReadWriteLock 是一种读写锁,允许多个读线程同时访问,但写线程独占锁。
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class Example {
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();
}
}
}
4. StampedLock
StampedLock 是Java 8引入的锁机制,支持乐观读锁、悲观读锁和写锁。
import java.util.concurrent.locks.StampedLock;
public class Example {
private final StampedLock stampedLock = new StampedLock();
public void readMethod() {
long stamp = stampedLock.readLock();
try {
// 读操作
} finally {
stampedLock.unlockRead(stamp);
}
}
public void writeMethod() {
long stamp = stampedLock.writeLock();
try {
// 写操作
} finally {
stampedLock.unlockWrite(stamp);
}
}
public void optimisticReadMethod() {
long stamp = stampedLock.tryOptimisticRead();
// 读操作
if (!stampedLock.validate(stamp)) {
stamp = stampedLock.readLock();
try {
// 重新读操作
} finally {
stampedLock.unlockRead(stamp);
}
}
}
}
5. Semaphore
Semaphore 是一种计数信号量,用于控制同时访问特定资源的线程数量。
import java.util.concurrent.Semaphore;
public class Example {
private final Semaphore semaphore = new Semaphore(10); // 允许10个线程同时访问
public void method() throws InterruptedException {
semaphore.acquire(); // 获取许可
try {
// 同步代码
} finally {
semaphore.release(); // 释放许可
}
}
}
6. Condition
Condition 通常与 ReentrantLock 配合使用,用于线程间的协调。
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Example {
private final Lock 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();
}
}
}
7. Atomic 类
Atomic 类(如 AtomicInteger、AtomicReference 等)通过CAS(Compare-And-Swap)实现无锁同步。
import java.util.concurrent.atomic.AtomicInteger;
public class Example {
private final AtomicInteger atomicInteger = new AtomicInteger(0);
public void increment() {
atomicInteger.incrementAndGet(); // 原子操作
}
}
8. LockSupport
LockSupport 提供了线程阻塞和唤醒的基本操作。
import java.util.concurrent.locks.LockSupport;
public class Example {
public void parkMethod() {
LockSupport.park(); // 阻塞当前线程
}
public void unparkMethod(Thread thread) {
LockSupport.unpark(thread); // 唤醒指定线程
}
}
总结
synchronized:简单易用,适合大多数场景。ReentrantLock:提供更多功能,如可中断锁、超时锁等。ReadWriteLock:适合读多写少的场景。StampedLock:性能更高,适合复杂场景。Semaphore:控制资源访问数量。Condition:用于线程间协调。Atomic 类:无锁同步,适合简单操作。LockSupport:底层线程阻塞和唤醒工具。
根据具体需求选择合适的加锁方式。