本文目录导读:

Java中使用悲观锁的案例
悲观锁的核心思想是:在访问共享资源前,先锁定资源,确保其他线程无法同时访问,以下是几种常见的实现方式:
synchronized 关键字(最基础)
public class PessimisticLockExample {
private int count = 0;
private final Object lock = new Object();
// 方法级别的悲观锁
public synchronized void increment() {
count++;
}
// 代码块级别的悲观锁(更灵活)
public void decrement() {
synchronized (lock) {
count--;
}
}
}
ReentrantLock(可重入锁)
import java.util.concurrent.locks.ReentrantLock;
public class BankAccount {
private double balance;
private final ReentrantLock lock = new ReentrantLock();
public BankAccount(double initialBalance) {
this.balance = initialBalance;
}
// 转账方法 - 使用悲观锁
public void transfer(double amount) {
lock.lock(); // 获取锁
try {
if (balance >= amount) {
System.out.println(Thread.currentThread().getName() + " 开始转账: " + amount);
Thread.sleep(100); // 模拟耗时操作
balance -= amount;
System.out.println(Thread.currentThread().getName() + " 转账成功,余额: " + balance);
} else {
System.out.println("余额不足,当前余额: " + balance);
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
lock.unlock(); // 释放锁
}
}
public static void main(String[] args) {
BankAccount account = new BankAccount(1000);
// 模拟多个用户同时转账
for (int i = 0; i < 5; i++) {
new Thread(() -> {
account.transfer(200);
}).start();
}
}
}
数据库层面的悲观锁(Java + MySQL)
import java.sql.*;
public class DatabasePessimisticLock {
// 使用 SELECT ... FOR UPDATE 加悲观锁
public void updateWitnPessimisticLock(int productId, int quantity) {
String selectSql = "SELECT quantity FROM products WHERE id = ? FOR UPDATE";
String updateSql = "UPDATE products SET quantity = ? WHERE id = ?";
try (Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "password");
PreparedStatement selectStmt = conn.prepareStatement(selectSql);
PreparedStatement updateStmt = conn.prepareStatement(updateSql)) {
// 开启事务
conn.setAutoCommit(false);
// 查询并加锁
selectStmt.setInt(1, productId);
ResultSet rs = selectStmt.executeQuery();
if (rs.next()) {
int currentQuantity = rs.getInt("quantity");
if (currentQuantity >= quantity) {
// 更新库存
updateStmt.setInt(1, currentQuantity - quantity);
updateStmt.setInt(2, productId);
updateStmt.executeUpdate();
conn.commit();
System.out.println("库存更新成功");
} else {
conn.rollback();
System.out.println("库存不足");
}
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
实际应用场景:库存扣减系统
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.atomic.AtomicInteger;
public class InventorySystem {
private AtomicInteger stock = new AtomicInteger(100);
private final ReentrantLock lock = new ReentrantLock(true); // 公平锁
// 使用悲观锁确保库存操作原子性
public boolean deductStock(int quantity) {
lock.lock();
try {
// 模拟业务处理时间
Thread.sleep(50);
int currentStock = stock.get();
if (currentStock >= quantity) {
// 扣减库存
stock.addAndGet(-quantity);
System.out.println(Thread.currentThread().getName() +
" 扣减成功,当前库存: " + stock.get());
return true;
} else {
System.out.println(Thread.currentThread().getName() +
" 库存不足,当前库存: " + currentStock + ",需要: " + quantity);
return false;
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return false;
} finally {
lock.unlock();
}
}
public static void main(String[] args) {
InventorySystem system = new InventorySystem();
// 模拟并发购买
for (int i = 0; i < 10; i++) {
final int quantity = 10;
new Thread(() -> {
system.deductStock(quantity);
}, "用户-" + i).start();
}
}
}
性能对比与选择建议
| 特性 | synchronized | ReentrantLock | 数据库锁 |
|---|---|---|---|
| 使用简便性 | ✅ 简单 | ⚠️ 较复杂 | ❌ 复杂 |
| 性能 | ❌ 较差 | ✅ 较好 | ⚠️ 一般 |
| 灵活性 | ❌ 低 | ✅ 高 | ✅ 高 |
| 超时机制 | ❌ 不支持 | ✅ 支持 | ✅ 支持 |
| 公平性 | ❌ 非公平 | ✅ 可选择 | ⚠️ 取决于DB |
使用建议
- 小规模并发:使用
synchronized即可 - 高性能需求:使用
ReentrantLock - 分布式系统:使用数据库锁或分布式锁(如 Redis、Zookeeper)
- 锁的范围要小:尽量缩小加锁的代码块
- 避免死锁:注意锁的获取顺序,使用 tryLock 避免无限等待
在实际项目中,优先使用无锁或乐观锁(如 AtomicInteger、CAS),只有在冲突概率较高时才考虑悲观锁。
版权声明: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直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播