本文目录导读:

我来给你一个完整的Java读写锁(ReentrantReadWriteLock)案例,包含详细注释和易用场景。
基础案例:缓存示例
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
/**
* 使用读写锁实现的缓存系统
* 特点:读读不互斥、读写互斥、写写互斥
*/
public class ReadWriteLockCache<K, V> {
private final Map<K, V> cache = new HashMap<>();
private final ReadWriteLock lock = new ReentrantReadWriteLock();
// 写入数据(独占锁)
public void put(K key, V value) {
lock.writeLock().lock();
try {
System.out.println(Thread.currentThread().getName() + " 正在写入: " + key + "=" + value);
Thread.sleep(100); // 模拟耗时操作
cache.put(key, value);
System.out.println(Thread.currentThread().getName() + " 写入完成");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.writeLock().unlock();
}
}
// 读取数据(共享锁)
public V get(K key) {
lock.readLock().lock();
try {
System.out.println(Thread.currentThread().getName() + " 正在读取: " + key);
Thread.sleep(100); // 模拟耗时操作
V value = cache.get(key);
System.out.println(Thread.currentThread().getName() + " 读取完成: " + value);
return value;
} catch (InterruptedException e) {
e.printStackTrace();
return null;
} finally {
lock.readLock().unlock();
}
}
// 测试代码
public static void main(String[] args) {
ReadWriteLockCache<String, String> cache = new ReadWriteLockCache<>();
// 多个写线程
for (int i = 0; i < 3; i++) {
final int index = i;
new Thread(() -> {
cache.put("key" + index, "value" + index);
}, "写线程-" + i).start();
}
// 多个读线程
for (int i = 0; i < 5; i++) {
final int index = i;
new Thread(() -> {
cache.get("key" + index);
}, "读线程-" + i).start();
}
}
}
读写锁降级示例
import java.util.concurrent.locks.ReentrantReadWriteLock;
/**
* 演示锁降级:写锁 -> 读锁
* 锁降级是指将写锁降级为读锁
*/
public class LockDowngradeDemo {
private final ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
private int data = 0;
private boolean updated = false;
/**
* 锁降级的正确使用:
* 1. 获取写锁
* 2. 获取读锁
* 3. 释放写锁
* 4. 释放读锁
*/
public void processData() {
rwLock.readLock().lock();
if (!updated) {
// 必须释放读锁才能获取写锁(锁升级不允许)
rwLock.readLock().unlock();
// 获取写锁
rwLock.writeLock().lock();
try {
// 再次检查状态(双重检查模式)
if (!updated) {
data = (int) (Math.random() * 100);
System.out.println(Thread.currentThread().getName()
+ " 更新数据为: " + data);
updated = true;
}
// 锁降级:在持有写锁的情况下获取读锁
rwLock.readLock().lock();
} finally {
// 释放写锁
rwLock.writeLock().unlock();
}
}
try {
// 此时持有读锁,可以安全读取
System.out.println(Thread.currentThread().getName()
+ " 读取数据: " + data);
} finally {
// 释放读锁
rwLock.readLock().unlock();
}
}
public static void main(String[] args) {
LockDowngradeDemo demo = new LockDowngradeDemo();
// 多个线程同时处理数据
for (int i = 0; i < 5; i++) {
new Thread(() -> {
demo.processData();
}, "线程-" + i).start();
}
}
}
公平与非公平模式对比
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class FairnessDemo {
public static void testFairness(boolean fair) {
ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
System.out.println("\n" + (fair ? "=== 公平模式 ===" : "=== 非公平模式 ==="));
// 创建多个写线程
Runnable writeTask = () -> {
lock.writeLock().lock();
try {
System.out.println(Thread.currentThread().getName() + " 获取写锁");
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
System.out.println(Thread.currentThread().getName() + " 释放写锁");
lock.writeLock().unlock();
}
};
// 创建多个读线程
Runnable readTask = () -> {
lock.readLock().lock();
try {
System.out.println(Thread.currentThread().getName() + " 获取读锁");
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
System.out.println(Thread.currentThread().getName() + " 释放读锁");
lock.readLock().unlock();
}
};
// 启动线程
Thread[] threads = new Thread[8];
for (int i = 0; i < 4; i++) {
threads[i * 2] = new Thread(readTask, "读线程-" + i);
threads[i * 2 + 1] = new Thread(writeTask, "写线程-" + i);
}
for (Thread t : threads) {
t.start();
}
// 等待所有线程完成
for (Thread t : threads) {
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
// 测试公平模式
testFairness(true);
// 测试非公平模式
testFairness(false);
}
}
实际业务场景:订单服务
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
/**
* 订单服务:演示读写锁在真实业务中的应用
*/
public class OrderService {
// 订单数据库模拟
private static class Order {
String orderId;
String status;
double amount;
Order(String orderId, String status, double amount) {
this.orderId = orderId;
this.status = status;
this.amount = amount;
}
@Override
public String toString() {
return String.format("Order{id='%s', status='%s', amount=%.2f}",
orderId, status, amount);
}
}
private final Map<String, Order> orderDB = new HashMap<>();
private final ReadWriteLock lock = new ReentrantReadWriteLock(true); // 公平锁
public OrderService() {
// 初始化一些订单
for (int i = 1; i <= 5; i++) {
orderDB.put("ORD" + i, new Order("ORD" + i, "已创建", 100.00 * i));
}
}
// 查询订单(读操作)
public Order getOrder(String orderId) {
lock.readLock().lock();
try {
System.out.println(Thread.currentThread().getName()
+ " 查询订单 " + orderId);
Thread.sleep(100);
return orderDB.get(orderId);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return null;
} finally {
lock.readLock().unlock();
}
}
// 更新订单状态(写操作)
public boolean updateOrderStatus(String orderId, String newStatus) {
lock.writeLock().lock();
try {
System.out.println(Thread.currentThread().getName()
+ " 更新订单 " + orderId + " 状态为: " + newStatus);
Order order = orderDB.get(orderId);
if (order == null) {
return false;
}
Thread.sleep(200); // 模拟数据库更新操作
order.status = newStatus;
System.out.println(Thread.currentThread().getName()
+ " 订单更新成功");
return true;
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return false;
} finally {
lock.writeLock().unlock();
}
}
// 批量查询(读操作)
public void batchQuery() {
lock.readLock().lock();
try {
System.out.println(Thread.currentThread().getName() + " 开始批量查询");
orderDB.entrySet().stream()
.limit(3)
.forEach(e -> System.out.println(" " + e.getValue()));
Thread.sleep(200);
System.out.println(Thread.currentThread().getName() + " 批量查询完成");
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
lock.readLock().unlock();
}
}
public static void main(String[] args) {
OrderService service = new OrderService();
// 模拟订单处理场景
System.out.println("=== 订单处理系统启动 ===\n");
// 多个查询线程(读)
for (int i = 0; i < 4; i++) {
new Thread(() -> {
service.getOrder("ORD" + (1 + (int)(Math.random() * 5)));
service.batchQuery();
}, "查询线程-" + i).start();
}
// 多个更新线程(写)
for (int i = 0; i < 3; i++) {
new Thread(() -> {
service.updateOrderStatus("ORD" + (1 + (int)(Math.random() * 5)),
"已支付");
}, "更新线程-" + i).start();
}
}
}
读锁重入示例
import java.util.concurrent.locks.ReentrantReadWriteLock;
/**
* 展示读写锁的重入特性
*/
public class LockReentrantDemo {
private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
public void readReentrant() {
rwl.readLock().lock();
try {
System.out.println(Thread.currentThread().getName()
+ " 第一次获取读锁");
// 读锁可以重入
rwl.readLock().lock();
try {
System.out.println(Thread.currentThread().getName()
+ " 第二次获取读锁(重入)");
} finally {
rwl.readLock().unlock();
System.out.println(Thread.currentThread().getName()
+ " 释放第二次读锁");
}
} finally {
rwl.readLock().unlock();
System.out.println(Thread.currentThread().getName()
+ " 释放第一次读锁");
}
}
public static void main(String[] args) {
LockReentrantDemo demo = new LockReentrantDemo();
// 多个线程测试读锁重入
for (int i = 0; i < 3; i++) {
new Thread(() -> {
demo.readReentrant();
}, "线程-" + i).start();
}
}
}
-
锁特性:
readLock():共享锁,允许多个线程同时读writeLock():独占锁,写时不允许读和写
-
锁降级:
- 写锁可以降级为读锁(持有写锁时获取读锁)
- 读锁不能升级为写锁(否则会死锁)
-
性能考量:
- 读多写少的场景使用读写锁性能较好
- 读少写多时,考虑普通锁或更高级的锁
-
注意事项:
- 读写锁非公平模式下,可防止写线程饿死
- 公平模式下,线程按请求顺序获取锁
- 释放锁时要放在finally块中
-
使用场景:
- 缓存系统
- 配置管理
- 订单系统
- 数据库连接池
- 任何读多写少的并发场景
这些示例涵盖了读写锁的主要使用场景和特性,你可以根据实际需求调整和使用。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播