Java 多线程进阶讲解与各种锁机制
在 Java 多线程编程中,锁机制是保证线程安全的重要手段。本文将深入探讨 Java 中的各种锁机制,包括 synchronized
、ReentrantLock
、ReadWriteLock
、StampedLock
等,并通过代码示例详细讲解其用法。
1. synchronized
关键字
synchronized
是 Java 中最基本的锁机制,可以修饰方法或代码块,确保同一时间只有一个线程可以访问共享资源。
修饰方法
1 2 3 4 5 6 7 8 9 10 11
| class Counter { private int count = 0;
public synchronized void increment() { count++; }
public int getCount() { return count; } }
|
修饰代码块
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| class Counter { private int count = 0; private final Object lock = new Object();
public void increment() { synchronized (lock) { count++; } }
public int getCount() { return count; } }
|
特点:
简单易用,无需手动释放锁。
性能较低,不适合高并发场景。
2. ReentrantLock
ReentrantLock 是 java.util.concurrent.locks 包中的一个类,提供了比 synchronized 更灵活的锁机制。
基本用法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock;
class Counter { private int count = 0; private final Lock lock = new ReentrantLock();
public void increment() { lock.lock(); try { count++; } finally { lock.unlock(); } }
public int getCount() { return count; } }
|
可重入性
ReentrantLock 是可重入锁,同一个线程可以多次获取同一把锁。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| public void methodA() { lock.lock(); try { methodB(); } finally { lock.unlock(); } }
public void methodB() { lock.lock(); try { } finally { lock.unlock(); } }
|
特点:
支持公平锁和非公平锁。
支持尝试获取锁(tryLock)和超时机制。
需要手动释放锁。
3. ReadWriteLock
ReadWriteLock 是一种读写分离锁,允许多个读线程同时访问共享资源,但写线程独占资源。
基本用法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock;
class SharedData { private int data = 0; private final ReadWriteLock rwLock = new ReentrantReadWriteLock();
public void write(int value) { rwLock.writeLock().lock(); try { data = value; } finally { rwLock.writeLock().unlock(); } }
public int read() { rwLock.readLock().lock(); try { return data; } finally { rwLock.readLock().unlock(); } } }
|
特点:
读操作可以并发执行,写操作独占资源。
适合读多写少的场景。
4. StampedLock
StampedLock 是 Java 8 引入的一种新型锁,提供了更高的性能,支持乐观读锁。
基本用法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| import java.util.concurrent.locks.StampedLock;
class SharedData { private int data = 0; private final StampedLock stampedLock = new StampedLock();
public void write(int value) { long stamp = stampedLock.writeLock(); try { data = value; } finally { stampedLock.unlockWrite(stamp); } }
public int read() { long stamp = stampedLock.tryOptimisticRead(); int currentData = data; if (!stampedLock.validate(stamp)) { stamp = stampedLock.readLock(); try { currentData = data; } finally { stampedLock.unlockRead(stamp); } } return currentData; } }
|
特点:
支持乐观读锁,减少锁竞争。
性能优于 ReadWriteLock,但使用更复杂。
5. 锁的性能比较
锁类型 特点 适用场景
synchronized 简单易用,性能较低 低并发场景
ReentrantLock 灵活,支持公平锁、非公平锁、超时机制 高并发场景
ReadWriteLock 读写分离,读操作并发执行 读多写少的场景
StampedLock 高性能,支持乐观读锁 读多写少且对性能要求高的场景
6. 总结
synchronized 是最基本的锁机制,适合简单的并发场景。
ReentrantLock 提供了更灵活的锁控制,适合高并发场景。
ReadWriteLock 实现了读写分离,适合读多写少的场