ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

锁的失效和分布式锁的实现

2026/8/5 8:37:19 拓冰建站 浏览量
锁的失效和分布式锁的实现

1. 引言

在多线程编程和分布式系统设计中,锁是保证数据一致性和线程安全的重要机制。本文将深入探讨从单体式应用到分布式系统中锁的实现与演进。

2. 单体式项目中的锁

2.1 synchronized关键字

在单体式项目中,最简单的加锁方式是使用synchronized关键字。

加在方法上的synchronized(不推荐)

public synchronized void process() {// 业务逻辑
}

这种方式会锁定整个方法,导致性能较差,因为同一时间只能有一个线程访问该方法。

同步代码块(推荐)

public void process() {synchronized(lockObject) {// 业务逻辑}
}

这种方式只锁定特定的代码块,性能更好,但需要确保锁定的是同一个对象。

2.2 锁对象的注意事项

Integer类型的陷阱

// 错误示例
Integer id;
synchronized(id) {
}// 正确方式
synchronized(id.toString().intern()) {
}
// 原因:Integer类型只有在保留字-127-128这个范围里,值相对的对象是判定为同一个对象的
//      如果值超过了这一个范围,视为每一个对象都是新对象,锁就会失效
//      为了解决这个问题,尝试通过toString()方法将它转换成字符类型
//      但是通过toString()方法创建的字符类型对象也是每个都是新的对象
//      因此需要使用intern()方法,使得只要值相等的对象都看作是同一个对象

2.3 ReentrantLock

除了synchronized,Java还提供了更灵活的ReentrantLock:

ReentrantLock lock = new ReentrantLock(); // 非公平锁
ReentrantLock fairLock = new ReentrantLock(true); // 公平锁public void process() {lock.lock();try {// 业务逻辑} finally {lock.unlock();}
}

3. 分布式环境下的锁挑战

在分布式系统中,单体式的锁机制失效了,因为每个服务节点都有自己的JVM,锁只能控制当前节点。

3.1 基于Redis的分布式锁

简单的setnx实现

SETNX lock_key unique_value

但这种实现存在多个问题:

  • 锁无法自动释放
  • 过期时间设置困难
  • 存在死锁风险

4. Redisson分布式锁解决方案

4.1 基本使用

RLock lock = redisson.getLock(id);
lock.lock();
try {// 业务逻辑
} finally {lock.unlock();
}

4.2 看门狗机制

Redisson的看门狗机制会自动续期锁的过期时间:

  • 默认过期时间30秒
  • 看门狗每10秒检查一次,如果业务未完成则自动续期
  • 避免业务执行时间超过锁过期时间导致的问题

4.3 红锁(RedLock)

在Redis集群环境下,红锁算法确保分布式锁的可靠性:

RedissonRedLock lock = new RedissonRedLock(lock1, lock2, lock3);
lock.lock();
try {// 业务逻辑
} finally {lock.unlock();
}

红锁要求大多数(N/2+1)Redis节点成功获取锁才算真正获取到锁。

4.4 实现原理

Redisson通过LUA脚本保证原子性操作:

if redis.call('exists', KEYS[1]) == 0 then redis.call('hset', KEYS[1], ARGV[2], 1);redis.call('pexpire', KEYS[1], ARGV[1]);return nil;
end;

5. 总结

从单体式锁到分布式锁的演进体现了系统架构的发展需求:

  • 单体项目:synchronized和ReentrantLock足够应对
  • 分布式系统:需要基于Redis等中间件实现分布式锁
  • Redisson提供了生产级别的分布式锁解决方案
  • 看门狗机制和红锁算法进一步增强了可靠性和可用性

选择合适的锁机制需要根据具体的业务场景和系统架构来决定,在保证数据一致性的同时,也要考虑性能和可用性的平衡。