Java中的锁机制全解析:从synchronized到分布式锁

在多线程编程中,锁是保证线程安全的核心工具。本文将详解Java中常见的锁机制及其实际应用场景,帮助开发者选择最合适的锁方案。

一、内置锁:synchronized

原理

通过JVM内置的监视器锁(Monitor)实现,可修饰方法或代码块。

// 修饰方法
public synchronized void add() {
    // 线程安全操作
}

// 修饰代码块
public void increment() {
    synchronized(this) {
        // 线程安全操作
    }
}

场景

  • 单机简单同步:如计数器、对象状态变更

  • 资源竞争低:性能要求不高的场景

二、显式锁:ReentrantLock

特性

  • 可重入性

  • 支持公平/非公平锁

  • 尝试获取锁(tryLock)

  • 可中断锁

ReentrantLock lock = new ReentrantLock();

public void performTask() {
    lock.lock();
    try {
        // 临界区操作
    } finally {
        lock.unlock(); // 必须手动释放
    }
}

场景

  • 复杂同步逻辑:需要尝试获取锁

if (lock.tryLock(1, TimeUnit.SECONDS)) {
    try {
        // 获取锁成功
    } finally {
        lock.unlock();
    }
}
  • 公平性要求:防止线程饥饿

  • 锁分离:配合Condition实现等待通知机制

三、读写锁:ReentrantReadWriteLock

原理

分离读锁(共享)和写锁(独占),提升读多写少场景的性能。

ReadWriteLock rwLock = new ReentrantReadWriteLock();

public void readData() {
    rwLock.readLock().lock();
    try {
        // 读取操作
    } finally {
        rwLock.readLock().unlock();
    }
}

public void writeData() {
    rwLock.writeLock().lock();
    try {
        // 写入操作
    } finally {
        rwLock.writeLock().unlock();
    }
}

场景

  • 缓存系统:如热点数据缓存

  • 配置中心:频繁读取,偶尔更新配置

四、乐观锁:StampedLock(JDK8+)

特性

  • 乐观读锁

  • 锁升级机制

StampedLock stampedLock = new StampedLock();

// 乐观读
public double read() {
    long stamp = stampedLock.tryOptimisticRead();
    // 读取数据...
    if (!stampedLock.validate(stamp)) {
        stamp = stampedLock.readLock(); // 升级为悲观锁
        try {
            // 重新读取
        } finally {
            stampedLock.unlockRead(stamp);
        }
    }
    return data;
}

// 写锁
public void write() {
    long stamp = stampedLock.writeLock();
    try {
        // 写操作
    } finally {
        stampedLock.unlockWrite(stamp);
    }
}

场景

  • 高并发读:如股票行情系统

  • 数据校验:先快速读取后验证

五、分布式锁

实现方式

  • Redis(RedLock算法)

  • ZooKeeper(临时有序节点)

  • 数据库(唯一约束)

// Redis分布式锁示例(Jedis)
public boolean tryLock(String key, String value, int expire) {
    return "OK".equals(jedis.set(key, value, "NX", "EX", expire));
}

public void unlock(String key, String value) {
    if (value.equals(jedis.get(key))) {
        jedis.del(key);
    }
}

场景

  • 分布式系统:集群服务定时任务

  • 资源抢占:如秒杀系统库存扣减

六、锁优化实践

  1. 减小锁粒度:ConcurrentHashMap分段锁

  2. 无锁编程:Atomic原子类

  3. 避免死锁:按顺序获取锁

  4. 锁分离:读写锁分离

总结对比

锁类型特性适用场景
synchronized自动释放,非中断简单同步
ReentrantLock灵活控制,可中断复杂同步逻辑
ReadWriteLock读写分离读多写少
StampedLock乐观读,高性能高并发读
分布式锁跨JVM分布式系统

选择合适的锁能显著提升系统性能。理解各锁的特性及适用场景,是构建高并发系统的关键技能。在实际开发中,建议先用synchronized,当需要更细粒度控制时再考虑显式锁。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码里看花‌

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值