本文目录导读:

我将为你全面介绍Java中的锁机制,包含各种锁的使用案例、实现原理和最佳实践。
synchronized 基础锁
同步方法案例
public class SynchronizedMethodExample {
private int count = 0;
// 同步实例方法
public synchronized void increment() {
count++;
}
// 同步静态方法
public synchronized static void staticMethod() {
System.out.println("静态同步方法");
}
// 使用示例
public static void main(String[] args) throws InterruptedException {
SynchronizedMethodExample example = new SynchronizedMethodExample();
// 创建10个线程同时增加count
Thread[] threads = new Thread[10];
for (int i = 0; i < 10; i++) {
threads[i] = new Thread(() -> {
for (int j = 0; j < 1000; j++) {
example.increment();
}
});
threads[i].start();
}
// 等待所有线程完成
for (Thread t : threads) {
t.join();
}
System.out.println("最终count值: " + example.count);
}
}
同步代码块案例
public class SynchronizedBlockExample {
private final Object lock = new Object();
private List<String> list = new ArrayList<>();
public void addItem(String item) {
// 使用专用的锁对象
synchronized (lock) {
list.add(item);
System.out.println(Thread.currentThread().getName() + " 添加元素: " + item);
}
}
public void removeItem(String item) {
synchronized (lock) {
if (list.contains(item)) {
list.remove(item);
System.out.println(Thread.currentThread().getName() + " 移除元素: " + item);
}
}
}
// 使用类对象作为锁
public static void printClassInfo() {
synchronized (SynchronizedBlockExample.class) {
System.out.println("类级别的锁");
}
}
}
ReentrantLock 可重入锁
基本使用案例
import java.util.concurrent.locks.ReentrantLock;
public class ReentrantLockExample {
private final ReentrantLock lock = new ReentrantLock();
private int count = 0;
public void increment() {
lock.lock();
try {
count++;
System.out.println(Thread.currentThread().getName() + " count: " + count);
Thread.sleep(50);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
lock.unlock(); // 确保解锁
}
}
// 可重入示例
public void outerMethod() {
lock.lock();
try {
System.out.println("外部方法");
innerMethod(); // 同一个线程可以再次获取锁
} finally {
lock.unlock();
}
}
public void innerMethod() {
lock.lock();
try {
System.out.println("内部方法");
} finally {
lock.unlock();
}
}
}
公平锁和超时锁案例
public class FairLockExample {
// 公平锁:多个线程按照申请锁的顺序获得锁
private final ReentrantLock fairLock = new ReentrantLock(true);
// 非公平锁:不保证顺序
private final ReentrantLock nonFairLock = new ReentrantLock(false);
public void tryLockWithTimeout() {
if (fairLock.tryLock()) {
try {
System.out.println("立即获取锁成功");
} finally {
fairLock.unlock();
}
}
}
public void tryLockDuration() {
try {
// 尝试在3秒内获取锁
if (fairLock.tryLock(3, TimeUnit.SECONDS)) {
try {
System.out.println("在3秒内获取到锁");
} finally {
fairLock.unlock();
}
} else {
System.out.println("3秒内未获取到锁");
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
可中断锁案例
public class InterruptibleLockExample {
private final ReentrantLock lock = new ReentrantLock();
public void interruptibleLock() throws InterruptedException {
System.out.println(Thread.currentThread().getName() + " 尝试获取锁");
// lockInterruptibly() 允许在等待锁时被中断
lock.lockInterruptibly();
try {
System.out.println(Thread.currentThread().getName() + " 获取到锁");
Thread.sleep(5000); // 模拟长时间工作
} finally {
lock.unlock();
System.out.println(Thread.currentThread().getName() + " 释放锁");
}
}
public static void main(String[] args) throws InterruptedException {
InterruptibleLockExample example = new InterruptibleLockExample();
Thread t1 = new Thread(() -> {
try {
example.interruptibleLock();
} catch (InterruptedException e) {
System.out.println(Thread.currentThread().getName() + " 被中断");
}
}, "线程1");
Thread t2 = new Thread(() -> {
try {
example.interruptibleLock();
} catch (InterruptedException e) {
System.out.println(Thread.currentThread().getName() + " 被中断");
}
}, "线程2");
t1.start();
Thread.sleep(100);
t2.start();
Thread.sleep(100);
t2.interrupt(); // 中断等待中的线程2
}
}
读写锁案例
ReentrantReadWriteLock
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class ReadWriteLockExample {
private final ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
private final ReentrantReadWriteLock.ReadLock readLock = rwLock.readLock();
private final ReentrantReadWriteLock.WriteLock writeLock = rwLock.writeLock();
private Map<String, String> cache = new HashMap<>();
// 读操作 - 可并发执行
public String get(String key) {
readLock.lock();
try {
System.out.println(Thread.currentThread().getName() + " 读取数据");
Thread.sleep(100);
return cache.get(key);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return null;
} finally {
readLock.unlock();
}
}
// 写操作 - 独占执行
public void put(String key, String value) {
writeLock.lock();
try {
System.out.println(Thread.currentThread().getName() + " 写入数据");
Thread.sleep(200);
cache.put(key, value);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
writeLock.unlock();
}
}
public static void main(String[] args) {
ReadWriteLockExample example = new ReadWriteLockExample();
// 多个读线程
for (int i = 0; i < 5; i++) {
new Thread(() -> {
for (int j = 0; j < 3; j++) {
example.get("key");
}
}, "读线程-" + i).start();
}
// 写线程
new Thread(() -> {
for (int i = 0; i < 3; i++) {
example.put("key", "value" + i);
}
}, "写线程").start();
}
}
StampedLock(Java 8+)
import java.util.concurrent.locks.StampedLock;
public class StampedLockExample {
private final StampedLock stampedLock = new StampedLock();
private double x, y;
// 独占写锁
public void move(double deltaX, double deltaY) {
long stamp = stampedLock.writeLock();
try {
x += deltaX;
y += deltaY;
} finally {
stampedLock.unlockWrite(stamp);
}
}
// 乐观读锁 - 允许其他线程写
public double distanceFromOrigin() {
long stamp = stampedLock.tryOptimisticRead();
double currentX = x;
double currentY = y;
// 检查读取期间是否有写入
if (!stampedLock.validate(stamp)) {
// 有写入,升级为悲观读锁
stamp = stampedLock.readLock();
try {
currentX = x;
currentY = y;
} finally {
stampedLock.unlockRead(stamp);
}
}
return Math.sqrt(currentX * currentX + currentY * currentY);
}
// 悲观读锁
public double readWithLock() {
long stamp = stampedLock.readLock();
try {
return Math.sqrt(x * x + y * y);
} finally {
stampedLock.unlockRead(stamp);
}
}
}
Condition 条件锁
生产者消费者案例
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class ProductConsumerExample {
private final ReentrantLock lock = new ReentrantLock();
private final Condition notEmpty = lock.newCondition();
private final Condition notFull = lock.newCondition();
private final Queue<Integer> queue = new LinkedList<>();
private final int maxSize = 5;
private int value = 0;
// 生产者
public void produce() {
lock.lock();
try {
// 队列已满,等待消费
while (queue.size() == maxSize) {
System.out.println("队列已满,生产者等待...");
notFull.await();
}
int producedValue = ++value;
queue.add(producedValue);
System.out.println("生产: " + producedValue + " 队列大小: " + queue.size());
Thread.sleep(500);
// 唤醒消费者
notEmpty.signalAll();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
lock.unlock();
}
}
// 消费者
public void consume() {
lock.lock();
try {
// 队列为空,等待生产
while (queue.isEmpty()) {
System.out.println("队列为空,消费者等待...");
notEmpty.await();
}
int consumedValue = queue.poll();
System.out.println("消费: " + consumedValue + " 队列大小: " + queue.size());
Thread.sleep(1000);
// 唤醒生产者
notFull.signalAll();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
lock.unlock();
}
}
public static void main(String[] args) {
ProductConsumerExample example = new ProductConsumerExample();
// 2个生产者线程
for (int i = 0; i < 2; i++) {
new Thread(() -> {
for (int j = 0; j < 10; j++) {
example.produce();
}
}, "生产者" + i).start();
}
// 3个消费者线程
for (int i = 0; i < 3; i++) {
new Thread(() -> {
for (int j = 0; j < 10; j++) {
example.consume();
}
}, "消费者" + i).start();
}
}
}
高级锁案例
Semaphore 信号量
import java.util.concurrent.Semaphore;
public class SemaphoreExample {
// 最多允许3个线程同时访问
private final Semaphore semaphore = new Semaphore(3);
public void accessResource() {
try {
semaphore.acquire();
System.out.println(Thread.currentThread().getName() + " 正在访问资源");
Thread.sleep(2000);
System.out.println(Thread.currentThread().getName() + " 完成访问");
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
semaphore.release();
}
}
public static void main(String[] args) {
SemaphoreExample example = new SemaphoreExample();
for (int i = 0; i < 10; i++) {
new Thread(example::accessResource, "线程" + i).start();
}
}
}
CountDownLatch 倒计时门闩
import java.util.concurrent.CountDownLatch;
public class CountDownLatchExample {
public static void main(String[] args) throws InterruptedException {
int threadCount = 5;
CountDownLatch latch = new CountDownLatch(threadCount);
// 启动5个线程
for (int i = 0; i < threadCount; i++) {
final int threadNum = i;
new Thread(() -> {
try {
System.out.println("线程" + threadNum + " 开始执行");
Thread.sleep(2000);
System.out.println("线程" + threadNum + " 执行完成");
latch.countDown(); // 计数器减1
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}).start();
}
System.out.println("主线程等待所有子线程完成...");
latch.await(); // 等待计数变为0
System.out.println("所有线程已完成,主线程继续执行");
}
}
CyclicBarrier 循环屏障
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
public class CyclicBarrierExample {
private final CyclicBarrier barrier;
private final int threadCount = 4;
public CyclicBarrierExample() {
// 当4个线程都到达屏障时,执行汇总任务
barrier = new CyclicBarrier(threadCount, () -> {
System.out.println("=== 所有线程已到达屏障,汇总开始 ===");
});
}
public void processData() {
try {
System.out.println(Thread.currentThread().getName() + " 开始处理数据");
Thread.sleep(1000 + (int)(Math.random() * 3000));
System.out.println(Thread.currentThread().getName() + " 完成处理,等待其他线程");
barrier.await(); // 等待其他线程
System.out.println(Thread.currentThread().getName() + " 继续执行后续工作");
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
CyclicBarrierExample example = new CyclicBarrierExample();
for (int i = 0; i < 4; i++) {
new Thread(example::processData, "线程" + i).start();
}
}
}
无锁编程案例
Atomic 原子类
import java.util.concurrent.atomic.*;
public class AtomicExample {
private final AtomicInteger count = new AtomicInteger(0);
private final AtomicReference<String> reference = new AtomicReference<>("初始值");
public void increment() {
// CAS操作
int oldValue = count.get();
while (!count.compareAndSet(oldValue, oldValue + 1)) {
oldValue = count.get();
}
}
// 使用Lambda表达式
public void safeIncrement() {
count.updateAndGet(x -> x + 1);
}
public static void main(String[] args) throws InterruptedException {
AtomicExample example = new AtomicExample();
for (int i = 0; i < 10; i++) {
new Thread(() -> {
for (int j = 0; j < 1000; j++) {
example.safeIncrement();
}
}).start();
}
Thread.sleep(2000);
System.out.println("最终结果: " + example.count.get());
}
}
锁性能比较案例
public class LockPerformanceComparison {
private static final int THREAD_COUNT = 4;
private static final int ITERATIONS = 1000000;
// 测试synchronized
public static void testSynchronized() throws InterruptedException {
Object lock = new Object();
long[] counts = {0};
Thread[] threads = new Thread[THREAD_COUNT];
for (int i = 0; i < THREAD_COUNT; i++) {
threads[i] = new Thread(() -> {
long localCount = 0;
for (int j = 0; j < ITERATIONS; j++) {
synchronized (lock) {
localCount++;
}
}
synchronized (lock) {
counts[0] += localCount;
}
});
threads[i].start();
}
for (Thread t : threads) t.join();
System.out.println("synchronized结果: " + counts[0]);
}
// 测试ReentrantLock
public static void testReentrantLock() throws InterruptedException {
ReentrantLock lock = new ReentrantLock();
long[] counts = {0};
Thread[] threads = new Thread[THREAD_COUNT];
for (int i = 0; i < THREAD_COUNT; i++) {
threads[i] = new Thread(() -> {
long localCount = 0;
for (int j = 0; j < ITERATIONS; j++) {
lock.lock();
try {
localCount++;
} finally {
lock.unlock();
}
}
lock.lock();
try {
counts[0] += localCount;
} finally {
lock.unlock();
}
});
threads[i].start();
}
for (Thread t : threads) t.join();
System.out.println("ReentrantLock结果: " + counts[0]);
}
// 测试AtomicInteger
public static void testAtomic() throws InterruptedException {
AtomicInteger counter = new AtomicInteger(0);
Thread[] threads = new Thread[THREAD_COUNT];
for (int i = 0; i < THREAD_COUNT; i++) {
threads[i] = new Thread(() -> {
for (int j = 0; j < ITERATIONS; j++) {
counter.incrementAndGet();
}
});
threads[i].start();
}
for (Thread t : threads) t.join();
System.out.println("AtomicInteger结果: " + counter.get());
}
}
最佳实践总结
锁选择指南
public class LockSelectionGuide {
/*
* 选择建议:
* 1. 简单同步:使用 synchronized
* 2. 需要高级特性(可中断、超时、公平性):使用 ReentrantLock
* 3. 读多写少:使用 ReadWriteLock 或 StampedLock
* 4. 计数器:使用 Atomic 类
* 5. 线程间协作:使用 Condition
* 6. 访问控制:使用 Semaphore
*/
}
锁优化技巧
public class LockOptimizationTips {
// 1. 缩小锁范围
private int count = 0;
public synchronized void badMethod() {
System.out.println("无关操作");
count++;
System.out.println("更多无关操作");
}
public void goodMethod() {
System.out.println("无关操作");
synchronized (this) {
count++;
}
System.out.println("更多无关操作");
}
}
Java提供了多种锁机制,选择时需要根据具体场景:
- synchronized:简单可靠,适合大多数同步需求
- ReentrantLock:功能强大,支持中断、超时、公平锁
- ReadWriteLock/StampedLock:优化读多写少场景
- Atomic:无锁操作,适合简单计数器
- Semaphore/CyclicBarrier/CountDownLatch:线程协作工具
记住三个原则:
- 尽量缩小锁的范围
- 避免死锁(按固定顺序获取锁)
- 使用try-finally确保锁一定会释放